Rustの列挙型のメモ。
列挙型は、取りうる値を定義するデータ構造。
〔可視性〕enum 列挙名〔<型引数1, 型引数2, …>〕 { 列挙子1, 列挙子2, 〜 }
enumの可視性をpubにすると、列挙子もpub扱いになる。
列挙子にデータや型を持たせることも出来る。
列挙子 列挙子<型引数, …> 列挙子{ フィールド名: 型, … } ←構造体と同様にフィールドを持つ定義方法 列挙子(型, …) ←タプル構造体と同じような定義方法
列挙子ごとに異なる持たせ方をすることが出来る。
構造体やタプル構造体と同じような定義方法をした場合、その列挙子を使う際に引数を渡す。
(Javaだと列挙型のコンストラクターで初期値を設定するようにして、列挙子ごとに異なる静的な値を保持しておくことが出来るが、Rustの列挙型では出来ない)
列挙型でも(構造体と同様に)implブロックでメソッドを定義することが出来る。
トレイトを実装することも出来る。
(Javaだと列挙型にメソッドを定義しておいて、列挙子ごとにオーバーライドして異なる実装をすることが出来るが、Rustの列挙型では列挙子個別のメソッドを実装することは出来ない)
pub enum CommitStatus { Default, Accepted, Available, Stored, Propagated, } impl CommitStatus { const fn as_str(&self) -> &'static str { match self { CommitStatus::Default => "COMMIT_STATUS_UNSPECIFIED", CommitStatus::Accepted => "ACCEPTED", CommitStatus::Available => "AVAILABLE", CommitStatus::Stored => "STORED", CommitStatus::Propagated => "PROPAGATED", } } }
列挙子を指定する際はいちいち「列挙型名::
」を付けないといけないが、useによって列挙子をインポートすれば付けなくて済む。[2024-09-18]
impl CommitStatus { const fn as_str(&self) -> &'static str { use CommitStatus::*; match self { Default => "COMMIT_STATUS_UNSPECIFIED", Accepted => "ACCEPTED", Available => "AVAILABLE", Stored => "STORED", Propagated => "PROPAGATED", } } }
(C言語の列挙型のような)データを持たない単純な列挙子しか持たない列挙型の場合、実体は数値になる。[2025-02-01]
なので、Copyトレイトを実装しておくと便利。
ついでに、等値比較できるようにEqトレイトも実装しておくと便利。
#[derive(Clone, Copy, Debug, PartialEq, Eq)] enum MyEnum { A, B, C, } fn main() { let value = MyEnum::A; let n = value as i32; println!("{:?}={}", value, n) }
↓実行結果
A=0
単純な列挙型の場合、#[repr]属性で値の型を指定することが出来る。
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(i32)] enum MyEnum { A, B, C, }
#[repr(u8)] enum MyEnum { A = 1, B = 2, C = -1, ←u8の範囲は0〜255なので、コンパイルエラー }