昨日の記事「[Rust] 『Go言語でつくるインタプリタ』Rustで読了」でも言及しましたが, enum に PartialOrd
を derive することができます. 本記事ではその挙動についてまとめます.
シンプルな例
enum を定義する際に PartialOrd
を derive すると, variant を定義した順に大きくなるように不等号が定義されます. なお PartialOrd
には PartialEq
が必要なので, 普通はこれを同時に derive することになると思います.
/// 主系列星のスペクトル型のハーバード分類
#[derive(PartialEq, PartialOrd)]
enum MainSequenceStar {
M, K, G, F, A, B, O,
}
fn main() {
assert!(MainSequenceStar::O > MainSequenceStar::B);
assert!(MainSequenceStar::G == MainSequenceStar::G);
}
variant がデータを持つ場合
variant がデータを持つ場合, それが PartialOrd
であれば PartialOrd
を derive することができます. 順番は, まず variant で比較した後に中のデータを比較することで決められます.
/// 4次元時空における定常ブラックホール解.
/// 値は質量を除いたパラメータ (a と Q).
#[derive(PartialEq, PartialOrd)]
enum BlackHole {
Schwarzschild,
Kerr{a: f32},
ReissnerNordstrom{q: f32},
KerrNewman{a: f32, q: f32},
}
fn main() {
assert!( BlackHole::Schwarzschild < BlackHole::Kerr{a: 0.} );
assert!( BlackHole::Kerr{a: 0.15} < BlackHole::Kerr{a: 0.99} );
assert!( std::mem::discriminant(&BlackHole::Kerr{a: 0.15}) == std::mem::discriminant(&BlackHole::Kerr{a: 0.99}) );
assert!( BlackHole::Kerr{a: 0.99} < BlackHole::KerrNewman{a: 0.2, q: 0.5} );
assert!( BlackHole::KerrNewman{a: 0.1, q: 0.99} < BlackHole::KerrNewman{a: 0.2, q: 0.1} );
}
このようにフィールドが複数ある場合, 定義した際に先にあるものから順に比較されます. なおこの振る舞いは struct に PartialOrd
を derive したときと同じです.