Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types Rust是否有一个与F#typedefs相当的惯用用法?_Types_Rust_Type Alias - Fatal编程技术网

Types Rust是否有一个与F#typedefs相当的惯用用法?

Types Rust是否有一个与F#typedefs相当的惯用用法?,types,rust,type-alias,Types,Rust,Type Alias,我正在用Rust 1.6编写我的现有代码,我发现在源语言中用typedef标记一个类型非常方便。例如,在我的纸牌游戏中,我在F#中有一个等级值,定义为: type Rank = uint8 从标题为: Rust提供了声明类型别名以给现有类型另一个名称的能力。为此,我们使用type关键字。例如,我们可以创建别名km到i32,如下所示: type Kilometers = i32; 现在,别名km是i32的同义词;[…],km不是一个单独的新类型。具有km类型的值将被视为与i32类型的值相同:

我正在用Rust 1.6编写我的现有代码,我发现在源语言中用typedef标记一个类型非常方便。例如,在我的纸牌游戏中,我在F#中有一个等级值,定义为:

type Rank = uint8
从标题为:

Rust提供了声明类型别名以给现有类型另一个名称的能力。为此,我们使用
type
关键字。例如,我们可以创建别名
km
i32
,如下所示:

type Kilometers = i32;
现在,别名
km
i32
的同义词;[…],
km
不是一个单独的新类型。具有
km
类型的值将被视为与
i32
类型的值相同:

type Kilometers = i32;

let x: i32 = 5;
let y: Kilometers = 5;

println!("x + y = {}", x + y);
还有很多你应该读的,但这回答了问题


作为一篇社论,我不认为类型别名非常适合人们使用它们的许多地方。假设您的
等级
类型表示与一副牌有关,我建议使用a或a。原因是使用类型别名可以执行以下操作:

let rank: Rank = 100;
这对于一副典型的纸牌来说是荒谬的。枚举是一个受限集。这意味着您永远不能创建无效的
排名

enum Rank {
    One, Two, Three, Four, Five,
    Six, Seven, Eight, Nine, Ten,
    Jack, Queen, King, Ace,
}

impl Rank {
    fn from_value(v: u8) -> Result<Rank, ()> {
        use Rank::*;

        let r = match v {
            1 => One,
            2 => Two,
            // ...
            _ => return Err(()),
        };
        Ok(r)
    }

    fn value(&self) -> u8 {
        use Rank::*;

        match *self {
            One => 1,
            Two => 2,
            // ...
        }
    }
}
并返回了一个
结果
,但随后认为这会让人困惑。:-)

我使用它们的另一种情况是缩短我不想隐藏的较大类型。这种情况发生在迭代器或
Result
s之类的类型上,您可以这样做。比如:

type CardResult<T> = Result<T, Error>;

fn foo() -> CardResult<String> {
    // ..
}
类型CardResult=结果;
fn foo()->CardResult{
// ..
}

感谢您快速而详细的回复!通常,我非常同意您使用枚举将我的值限制为标准组值。然而,在我的例子中,我一般使用术语“card”,而不是扑克牌,所以我需要一个未指定值的等级。如果我想要简单的替换,我应该使用一个类型别名,如果我想要施加额外的限制/逻辑,我应该使用一个新类型,我理解得正确吗?@ErikUggeldahl是的,听起来正确。一个新类型允许附加限制或逻辑,而别名只是相同事物的另一个名称。@ErikUggeldahl它不仅仅是限制值。别名不提供额外的类型安全性,因为它不是。。。新类型,但相同类型的另一个名称。您能够计算
秩/5
或将
传递给接受
u8
的函数有意义吗?因为类型别名允许您这样做(因为
Rank
u8
)。在Rust中通常使用类型别名是为了方便,因为您有一个非常长且复杂的类型,并且希望更简洁地引用它(但别名就是该类型,应该在任何地方都使用它来代替它)
type Error = ();
type CardResult<T> = Result<T, Error>;

fn foo() -> CardResult<String> {
    // ..
}