Розпакування опцій за допомогою ?
Ви можете розпаковувати Options за допомогою операторів match, але часто простіше
використовувати оператор ?. Якщо x є Option, тоді обчислення x? поверне
внутрішнє значення, якщо x є Some, інакше воно завершить виконання будь-якої
функції, яка виконується, і поверне 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)]
#[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));
}