Option
и unwrap
В последнем примере мы показали, что мы по собственному
желанию можем вызвать сбой программы. Мы сказали нашей
программе вызвать panic
, если принцессе подарят
несоответствующий подарок - змею. Но что если принцесса
ожидает подарок, но не получает его? Этот случай тоже плохой, так
что и он должен быть обработан!
Мы можем проверить пустую строку (""
) так же, как мы сделали это со змеёй.
Поскольку мы используем Rust, давайте укажем компилятору случаи, когда подарка нет.
Перечисление (enum
) из стандартной библиотеки (std
), называющееся Option<T>
, используется, когда значение может отсутствовать. Оно проявляется как одна из двух опций (option
s):
Some(T)
: элемент типаT
найденNone
: элемент не найден
Эти случаи могут быть явно обработаны через match
или неявно с unwrap
. Неявная обработка либо вернёт внутренний элемент, либо вызовет panic
.
Обратите внимание, что можно вручную настроить сообщение отображаемое при вызове panic
с помощью expect, но unwrap
в противном случае оставляет нам менее понятный вывод, чем явная обработка. В следующем примере явная обработка при желании даёт более контролируемый результат, сохраняя при этом возможности panic
.
// Простолюдин видел всё это, и может справиться с любым подарком хорошо. // Все подарки обрабатываются с помощью `match`. fn give_commoner(gift: Option<&str>) { // Укажите порядок действий для каждого случая. 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); }