Resultのmap - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## 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 is {}", n),
            Err(e) => println!("Error: {}", 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()`などのコンビネータを使うことができます。
    // この関数は`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 is {}", n),
            Err(e) => println!("Error: {}", e),
        }
    }

    fn main() {
        // ここは以前と変わらず、妥当な解を与えます。
        let twenty = multiply("10", "2");
        print(twenty);

        // こちらは今度は有益なエラーメッセージを与えます。
        let tt = multiply("t", "2");
        print(tt);
    }