Разворачивание Option с ?

Вы можете развернуть Option с использованием match, но часто проще бывает использовать оператор?. Если x - Option, то выражениеx? вернёт значение переменной, если x - Some, в противном же случае оно завершит выполнение текущей функции и вернёт None.

fn next_birthday(current_age: Option<u8>) -> Option<String> {
	// Если `current_age` == `None`, то возвращаем `None`.
	// Если `current_age` == `Some`, то содержащееся в ней `u8` будет присвоено переменной `next_age`
    let next_age: u8 = current_age?;
    Some(format!("В следующем году мне будет {}", 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`.
        // С ним кода будет больше. Попробуйте использовать в этом коде `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));
}