Result 型を使用してエラーを処理する

完了

Rust には、エラーを返して伝達するための Result<T, E> 列挙型が用意されています。 慣例として、Ok(T) バリアントは成功を表し、値が含まれています。Err(E) バリアントはエラーを表し、エラー値が含まれています。

Result<T, E> 列挙型は次のように定義されます。

enum Result<T, E> {
    Ok(T),  // A value T was obtained.
    Err(E), // An error of type E was encountered instead.
}

値が "存在しない" 可能性を記述する Option 型とは対照的に、Result 型は "失敗"する可能性がある場合に最適です。

Result 型にも unwrap メソッドと expect メソッドがあり、次のいずれかを実行します。

  • Ok バリアントの内部の値を返します。
  • バリアントが Err である場合は、プログラムをパニックにします。

Result の動作を見てみましょう。 次のコード例では、次のいずれかを返す safe_division 関数の実装があります。

  • 成功した除算の結果を保持する Ok バリアントの Result 値。
  • 構造体 DivisionByZeroError を保持する Err バリアント。これは、失敗した除算を通知します。
#[derive(Debug)]
struct DivisionByZeroError;

fn safe_division(dividend: f64, divisor: f64) -> Result<f64, DivisionByZeroError> {
    if divisor == 0.0 {
        Err(DivisionByZeroError)
    } else {
        Ok(dividend / divisor)
    }
}

fn main() {
    println!("{:?}", safe_division(9.0, 3.0));
    println!("{:?}", safe_division(4.0, 0.0));
    println!("{:?}", safe_division(0.0, 2.0));
}

このプログラムを確認するには、Rust Playground に移動してください。

出力は次のようになります。

Ok(3.0)
Err(DivisionByZeroError)
Ok(0.0)

DivisionByZeroError 構造体の前にある #[derive(Debug)] の部分は、デバッグのために型を印刷可能にするよう Rust コンパイラに指示するマクロです。 この概念については、後の "特徴" モジュールで詳しく説明します。