Result - 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`

`Result`は、リッチなバージョンの`Option`型で_値の不在_の可能性の代わりに_エラー_の可能性を示します。

つまり、`Result<T, E>`は以下の２つの結果を持ちます。

- `Ok<T>`：要素`T`が見つかった場合
- `Err<E>`：要素`E`とともにエラーが見つかった場合

慣例により、`Ok`が期待される結果であり、`Err`は期待されない結果です。

`Option`と同様、`Result`は多くのメソッドを持ちます。例えば`unwrap()`は、`T`もしくは`panic`をもたらします。エラーハンドリングでは、`Result`と`Option`で重複するコンビネータが多くあります。

Rustを書いていく中で、`parse()`メソッドなど、`Result`型を返すメソッドを目にするでしょう。文字列を他の型にパースすることは必ずしも成功する訳ではないため、`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`はプログラムを終了させて不快なエラーメッセージを出力します。

エラーメッセージを改善するために、リターン型に対してもっと明確になるべきで、またエラーを明示的に処理することを考えるべきです。

## `main`内で使う`Result`

`Result`型は、明示的な指定により`main`関数のリターン型にもなります。一般に、`main`関数は以下のような形になるでしょう。

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

一方`main`で`Result`をリターン型とすることも可能です。エラーが`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(())
    }