match gift {
Some("змея") => println!("Фу! Я унесу эту змею обратно в лес."),
Some(inner) => println!("{}? Как хороший.", inner),
None => println!("Нет подарка? Ну что же."),
}
}
// Наша защищённая принцесса будет паниковать при виде змей.
// Все подарки обрабатываются неявно через `unwrap`.
fn give_princess(gift: Option<&str>) {
// `unwrap` вызовет `panic` когда получит `None`.
let inside = gift.unwrap();
if inside == "змея" { panic!("AAAaaaaa!!!!"); }
println!("Я люблю {}!!!!!", inside);
}
fn main() {
let food = Some("капуста");
let snake = Some("змея");
let void = None;
give_commoner(food);
give_commoner(snake);
give_commoner(void);
let bird = Some("малиновка");
let nothing = None;
give_princess(bird);
give_princess(nothing);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Вы можете развернуть 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))
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Чтобы ваш код был более читаемым, вы можете составить цепочку из нескольких ?.
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));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
match - возможный метод для работы с Option. Однако постоянное его использование может быть утомительным, особенно с операциями, которые получают только проверенные данные. В этом случае можно использовать комбинаторы, которые позволяют управлять потоком выполнения в модульном режиме.
Option имеет встроенный метод, зовущийся map(), комбинатор для простого преобразования Some -> Some и None -> None. Для большей гибкости, несколько вызовов map() могут быть связаны друг с другом в цепочку.