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

Resultmap

前の例の multiply でパニックさせるのは、堅牢なコードとは言えません。 一般的には、エラーを呼び出し元に返し、エラーに対してどのように応答するのが 適切かを呼び出し元が判断できるようにしたいものです。

まず、扱っているエラー型がどのようなものかを知る必要があります。 Err 型を特定するには、i32 に対して FromStr トレイトで 実装されている parse() を見ます。その結果、Err 型は ParseIntError として指定されます。

以下の例では、素直な match 文によって、全体としてより煩雑なコードになっています。

use std::num::ParseIntError;

// 戻り値の型を書き換えたので、`unwrap()` を使わずにパターンマッチングを使います。
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    match first_number_str.parse::<i32>() {
        Ok(first_number)  => {
            match second_number_str.parse::<i32>() {
                Ok(second_number)  => {
                    Ok(first_number * second_number)
                },
                Err(e) => Err(e),
            }
        },
        Err(e) => Err(e),
    }
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n は {}", n),
        Err(e) => println!("エラー: {}", e),
    }
}

fn main() {
    // これでも妥当な答えが表示されます。
    let twenty = multiply("10", "2");
    print(twenty);

    // 次は、はるかに有用なエラーメッセージを表示します。
    let tt = multiply("t", "2");
    print(tt);
}

幸いなことに、Optionmapand_then、そして他の多くのコンビネーターも Result に対して実装されています。Result に完全な一覧があります。

use std::num::ParseIntError;

// `Option` と同様に、`map()` などのコンビネーターを使えます。
// それ以外は、この関数は上のものと同じで、次のように読めます:
// 両方の値を str からパースできる場合は乗算し、そうでなければエラーを渡します。
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    first_number_str.parse::<i32>().and_then(|first_number| {
        second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
    })
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n は {}", n),
        Err(e) => println!("エラー: {}", e),
    }
}

fn main() {
    // これでも妥当な答えが表示されます。
    let twenty = multiply("10", "2");
    print(twenty);

    // 次は、はるかに有用なエラーメッセージを表示します。
    let tt = multiply("t", "2");
    print(tt);
}