Eri*_*ahl 12 types rust type-alias
我在Rust 1.6中重写了我的现有代码,我发现在源语言中通过typedef标记类型非常方便.例如,在我的纸牌游戏中,我将F#中的等级值定义为:
type Rank = uint8
Run Code Online (Sandbox Code Playgroud)
She*_*ter 22
来自Rust Programming Language部分标题为使用类型别名创建类型同义词:
Rust提供了声明类型别名的功能,以便为现有类型提供另一个名称.为此,我们使用type关键字.例如,我们可以创建别名Kilometers来i32,像这样:
type Kilometers = i32;
Run Code Online (Sandbox Code Playgroud)
现在,别名Kilometers是同义词i32; [...],Kilometers不是一个单独的新类型.具有该类型的值Kilometers将被视为与类型的值相同i32:
type Kilometers = i32;
let x: i32 = 5;
let y: Kilometers = 5;
println!("x + y = {}", x + y);
Run Code Online (Sandbox Code Playgroud)
还有更多你应该阅读,但这回答了这个问题.
作为一个社论,我不认为类型别名非常适合人们使用它们的很多地方.假设你的Rank类型代表的东西做的一副扑克牌,我建议任何一个enum或NEWTYPE.原因是使用类型别名可以执行以下操作:
let rank: Rank = 100;
Run Code Online (Sandbox Code Playgroud)
对于典型的牌组而言,这是荒谬的.枚举是限制集.这意味着您永远不能创建无效Rank:
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,
// ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
一个NEWTYPE是只是一个包装类型.与包装类型相比,它不会消耗额外的空间,它只提供一个实际的新类型,允许您实现可以限制为有效值的方法.可以创建无效值,但仅限于您自己的代码,而不是所有客户端代码:
struct Rank(u8);
impl Rank {
fn from_value(v: u8) -> Result<Rank, ()> {
if v >= 1 && v <= 14 {
Ok(Rank(v))
} else {
Err(())
}
}
fn value(&self) -> u8 {
self.0
}
}
Run Code Online (Sandbox Code Playgroud)
我倾向于使用类型别名作为类型的快速占位符.在编写上面的例子时,我实际上写道:
type Error = ();
Run Code Online (Sandbox Code Playgroud)
并返回了一个Result<Rank, Error>,但后来认为这会令人困惑.:-)
我使用它们的另一种情况是缩短我不想隐藏的更大类型.这种情况发生在迭代器或Results 等类型中,您可以在标准库中看到它们.就像是:
type CardResult<T> = Result<T, Error>;
fn foo() -> CardResult<String> {
// ..
}
Run Code Online (Sandbox Code Playgroud)