列挙型(enums)

Like tuples, enums can also be destructured by matching:

パターンは、変数を値の一部にバインドするためにも使用できます。以下のようにして、型の構造を調べることができます。単純な enum から始めましょう。

enum Result {
    Ok(i32),
    Err(String),
}

fn divide_in_two(n: i32) -> Result {
    if n % 2 == 0 {
        Result::Ok(n / 2)
    } else {
        Result::Err(format!("cannot divide {n} into two equal parts"))
    }
}

fn main() {
    let n = 100;
    match divide_in_two(n) {
        Result::Ok(half) => println!("{n} divided in two is {half}"),
        Result::Err(msg) => println!("sorry, an error happened: {msg}"),
    }
}

ここでは、アーム(arm, パターンを並べたもの)を使用して Result 値の分解を行っています。最初のアームでは、halfOk バリアント内の値にバインドされます。2 つ目のアームでは msg がエラー メッセージにバインドされます。

This slide should take about 4 minutes.
  • if/else 式は、後で match でアンパックされる列挙型を返しています。
  • 列挙型の定義に 3 つ目のバリアント(列挙型の要素のこと)を追加し、コード実行時にエラーを表示してみましょう。コードが網羅されていない箇所を示し、コンパイラがどのようにヒントを提供しようとしているかを説明します。
  • 列挙型バリアントの値には、パターンが一致した場合にのみアクセスできます。
  • 検索が網羅的でない場合にどうなるかを示します。すべてのケースが処理されるタイミングを確認することで、Rust コンパイラの利点を強調します。
  • divide_in_two の結果を result 変数に保存し、ループで match します。一致した場合は msg が使用されるため、コンパイルされません。これを修正するには、result ではなく &result でマッチします。これにより、msg は参照になるため、使用されなくなります。この 「マッチエルゴノミクス」 は、Rust 2018 で登場しました。古いRustをサポートする場合は、パターン内のmsgref msg に置き換えてください。