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 を展開する

Optionmatch 文を使って展開できますが、多くの場合は ? 演算子を使う方が簡単です。xOption の場合、x? を評価すると、xSome なら内側の値を返し、そうでなければ現在実行中の関数を終了して None を返します。

fn next_birthday(current_age: Option<u8>) -> Option<String> {
    // `current_age` が `None` の場合、これは `None` を返します。
    // `current_age` が `Some` の場合、内側の `u8` 値 + 1 が
    // `next_age` に代入されます
    let next_age: u8 = current_age? + 1;
    Some(format!("来年、私は{}歳になります", next_age))
}

複数の ? を連鎖させることで、コードをずっと読みやすくできます。

struct Person {
    job: Option<Job>,
}

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

#[derive(Clone, Copy)]
#[allow(dead_code)]
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));
}