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なので、コンパイルエラー
}