Option & unwrap
У останньому прикладі ми показали, що можемо навмисно викликати збій програми.
Ми сказали нашій програмі panic, якщо ми вип’ємо солодкий лимонад.
Але що, якщо ми очікуємо якийсь напій, але не отримуємо жодного?
Цей випадок був би так само поганим, тож його потрібно обробити!
Ми могли б перевіряти це на порожній рядок (""), як ми робимо з лимонадом.
Оскільки ми використовуємо Rust, натомість нехай компілятор вказує на випадки, де немає напою.
Перелік Option<T> у бібліотеці std використовується, коли відсутність є можливою. Він проявляється як одна з двох “опцій”:
Some(T): Елемент типуTбуло знайденоNone: Жодного елемента не було знайдено
Ці випадки можна або явно обробляти через match, або неявно за допомогою unwrap. Неявна обробка або поверне внутрішній елемент, або викличе panic.
Зверніть увагу, що panic можна вручну налаштувати за допомогою expect, але unwrap інакше залишає нам менш змістовний вивід, ніж явна обробка. У наведеному нижче прикладі явна обробка дає більш контрольований результат, зберігаючи водночас можливість викликати panic, якщо це потрібно.
// Дорослий бачив усе і може добре впоратися з будь-яким напоєм.
// Усі напої обробляються явно за допомогою `match`.
fn give_adult(drink: Option<&str>) {
// Визначте курс дій для кожного випадку.
match drink {
Some("lemonade") => println!("Yuck! Too sugary."),
Some(inner) => println!("{}? How nice.", inner),
None => println!("No drink? Oh well."),
}
}
// Інші викличуть `panic` перед тим, як пити солодкі напої.
// Усі напої обробляються неявно за допомогою `unwrap`.
fn drink(drink: Option<&str>) {
// `unwrap` повертає `panic`, коли отримує `None`.
let inside = drink.unwrap();
if inside == "lemonade" { panic!("AAAaaaaa!!!!"); }
println!("I love {}s!!!!!", inside);
}
fn main() {
let water = Some("water");
let lemonade = Some("lemonade");
let void = None;
give_adult(water);
give_adult(lemonade);
give_adult(void);
let coffee = Some("coffee");
let nothing = None;
drink(coffee);
drink(nothing);
}