本文へスキップ
BecomeCoder

Rustコース · 第7章 構造体とenum ― データを型で表す · レッスン29

enum ― とりうる種類を表す

ブラウザで完結

導入

「信号は 赤・黄・青 のどれか」「メッセージは 終了・移動・書き込み のどれか」——とりうる状態が決まっているものを表すのが enum(列挙型) です。Rust の enum は単なる定数の集まりではなく、各種類がデータを持てるのが強力な点です。

説明

enum Direction {
    North,
    South,
    East,
    West,
}

// 各種類がデータを持てる(ここが Rust の enum の真骨頂)
enum Message {
    Quit,                        // データなし
    Move { x: i32, y: i32 },     // 構造体のようなデータ
    Write(String),               // 文字列を1つ持つ
    ChangeColor(i32, i32, i32),  // タプルのようなデータ
}

fn main() {
    let dir = Direction::East;
    let msg = Message::Write(String::from("hello"));

    // enum は match で分岐するのが定番
    match msg {
        Message::Quit => println!("終了"),
        Message::Move { x, y } => println!("移動 ({x}, {y})"),
        Message::Write(text) => println!("書き込み: {text}"),
        Message::ChangeColor(r, g, b) => println!("色 ({r},{g},{b})"),
    }
}
  • enum Direction { North, ... } … 4つのうちどれか1つ、という型。値は Direction::North のように書きます。
  • Message の各種類は、それぞれ違う形のデータを持てますQuit(なし)、Move(名前付きフィールド)、Write文字列1つ)、ChangeColor(数値3つ)。1つの型で多様なケースを表現できます。
  • enum は match で分岐し、同時に中のデータを取り出せますMessage::Write(text)text に文字列が束縛される)。

第2章で学んだ match網羅性チェックが、enum で本領を発揮します。Message に新しい種類を追加すると、その種類を処理していない matchすべてコンパイルエラーになり、対応漏れを教えてくれます。「状態を増やしたのに処理を書き忘れる」バグを、コンパイラが潰してくれるのです。

試すには

上の match から1つの腕(たとえば Message::Quit =>)を消すと、「パターンが網羅されていない」とエラーになります。enum と match の組み合わせは、Rust で「ありうる状態を漏れなく扱う」ための中心的な道具です。

実際に動かしてみよう

下のエディタにRustを書いて「実行」を押すと、学習用シミュレータが println! の出力を表示します(本物のrustcではなく、教材の範囲を再現した軽量エンジンです)。struct・enum・match・トレイト・Vec/String/HashMap・Option/Result なども動きます。本文の例を書き換えて動かしてみましょう(所有権・借用チェッカーのコンパイルエラーは再現しないため、動きの確認用として使ってください)。

Rust — ブラウザ内で実行(学習用シミュレータ)

Rustの教材サブセットを動かす学習用シミュレータを読み込みます(本物のrustcではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。