私は既存のコードをRust 1.6で書き直していますが、ソース言語でtypedefで型にラベルを付けると非常に便利であることがわかりました。たとえば、私のカードゲームではF#のランク値は次のように定義されます。
type Rank = uint8
From The Rust Programming Language section title Creating Type Synonyms with Type Aliass :
Rustは、type aliasを宣言して、既存の型に別の名前を付ける機能を提供します。このために、type
キーワードを使用します。たとえば、次のようにエイリアスKilometers
からi32
を作成できます。
type Kilometers = i32;
現在、エイリアスKilometers
はi32
の同義語です。 [...]、Kilometers
は別個の新しいタイプではありません。タイプKilometers
の値は、タイプi32
の値と同じように扱われます。
type Kilometers = i32;
let x: i32 = 5;
let y: Kilometers = 5;
println!("x + y = {}", x + y);
あなたが読むべきものはもっとありますが、これは質問に答えます。
ちょっとした社説として、私はタイプエイリアスが人々がそれらを使用する多くの場所にぴったりだとは思いません。あなたのRank
タイプがトランプのデッキと関係があると仮定すると、 enum
または newtype 。その理由は、タイプエイリアスを使用すると、次のようなことができるためです。
let rank: Rank = 100;
これは、典型的なカードのデッキには無意味です。列挙型は制限されたセットです。これは、無効な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,
// ...
}
}
}
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
}
}
私は型のクイックプレースホルダーとして型エイリアスを使用する傾向があります。上記の例を書いている間、私は実際に次のように書いています。
type Error = ();
そしてResult<Rank, Error>
を返しましたが、それは混乱を招くと思いました。 :-)
私がそれらを使用する他のケースは、私が隠したくない大きなタイプを短くすることです。これは、イテレータやResult
sなどのタイプで発生します。これは 標準ライブラリを参照 です。何かのようなもの:
type CardResult<T> = Result<T, Error>;
fn foo() -> CardResult<String> {
// ..
}