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 の map

前の例の 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);
}

幸いなことに、Option の map、and_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);
}