Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Result

Result は、起こり得る_不在_ではなく、起こり得る_エラー_を表す、Option 型のより豊かなバージョンです。

つまり、Result<T, E> は次の 2 つの結果のいずれかを持ちます。

  • Ok(T): 要素 T が見つかった
  • Err(E): 要素 E とともにエラーが見つかった

慣例として、期待される結果は Ok であり、予期しない結果は Err です。

Option と同様に、Result には多くの関連メソッドがあります。たとえば unwrap() は、要素 T を返すか、panic します。ケース処理については、ResultOption の間に重複する多くのコンビネータがあります。

Rust を扱っていると、parse() メソッドのように、Result 型を返すメソッドに遭遇することが多いでしょう。文字列を別の型にパースできるとは限らないため、parse() は失敗の可能性を示す Result を返します。

文字列の parse() が成功する場合と失敗する場合に何が起こるかを見てみましょう。

fn multiply(first_number_str: &str, second_number_str: &str) -> i32 {
    // 数値を取り出すために `unwrap()` を使ってみましょう。痛い目に遭うでしょうか?
    let first_number = first_number_str.parse::<i32>().unwrap();
    let second_number = second_number_str.parse::<i32>().unwrap();
    first_number * second_number
}

fn main() {
    let twenty = multiply("10", "2");
    println!("double is {}", twenty);

    let tt = multiply("t", "2");
    println!("double is {}", tt);
}

失敗するケースでは、parse()unwrap()panic するためのエラーを残します。さらに、その panic はプログラムを終了させ、不快なエラーメッセージを表示します。

エラーメッセージの品質を向上させるには、戻り値の型をより具体的にし、エラーを明示的に処理することを検討すべきです。

mainResult を使用する

明示的に指定すれば、Result 型を main 関数の戻り値の型にすることもできます。通常、main 関数は次のような形式になります。

fn main() {
    println!("Hello World!");
}

しかし、mainResult の戻り値の型を持つこともできます。main 関数内でエラーが発生した場合、エラーコードを返し、エラーのデバッグ表現を出力します(Debug トレイトを使用します)。次の例はそのようなシナリオを示し、次のセクションで扱う内容にも触れています。

use std::num::ParseIntError;

fn main() -> Result<(), ParseIntError> {
    let number_str = "10";
    let number = match number_str.parse::<i32>() {
        Ok(number)  => number,
        Err(e) => return Err(e),
    };
    println!("{}", number);
    Ok(())
}