?によるOptionのアンパック - 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

# `?`による`Option`のアンパック

`Option`をアンパックするには`match`文を使うこともできますが、`?`を使う方が簡単になることが多いでしょう。`Option`の`x`があるとすると、`x?`を評価した値は、`x`が`Some`の場合は`x`に格納された値となり、そうでなければ実行中の関数を終了させ、`None`を返します。

    fn next_birthday(current_age: Option<u8>) -> Option<String> {
        // If `current_age` is `None`, this returns `None`.
        // If `current_age` is `Some`, the inner `u8` value + 1
        // gets assigned to `next_age`
        let next_age: u8 = current_age? + 1;
        Some(format!("Next year I will be {}", next_age))
    }

多くの`?`を共に使うことで、リーダブルなコードを書くことができます。

    struct Person {
        job: Option<Job>,
    }

    #[derive(Clone, Copy)]
    struct Job {
        phone_number: Option<PhoneNumber>,
    }

    #[derive(Clone, Copy)]
    struct PhoneNumber {
        area_code: Option<u8>,
        number: u32,
    }

    impl Person {

        // その人の市外局番が存在する場合、取得します。
        fn work_phone_area_code(&self) -> Option<u8> {
            // `?`がなければ、多くのネストされた`match`文を必要とするため、
            // より長いコードとなります。
            // 実際に書いて、どちらの方が簡単か確かめてみましょう。
            self.job?.phone_number?.area_code
        }
    }

    fn main() {
        let p = Person {
            job: Some(Job {
                phone_number: Some(PhoneNumber {
                    area_code: Some(61),
                    number: 439222222,
                }),
            }),
        };

        assert_eq!(p.work_phone_area_code(), Some(61));
    }