Option и unwrap
В последнем примере мы показали, что можем вызвать сбой программы по своему желанию. Мы сказали нашей программе вызвать panic, если мы выпьем сладкий лимонад. Но что, если ожидаем какой-то напиток, но не получаем его? Этот случай тоже плохой, так что и он должен быть обработан!
Мы могли бы сравнить значение с пустой строкой ("") так же, как мы сделали это с лимонадом. Поскольку мы используем Rust, пусть компилятор сам укажет нам случаи, когда напитка нет.
Перечисление (enum) из стандартной библиотеки (std), называющееся Option<T>, используется, когда значение может отсутствовать. Оно может находиться в одном из двух состояний:
Some(T): элемент типаTнайденNone: элемент не найден
Эти случаи могут быть или явно обработаны с помощью match, или неявно с unwrap. Неявная обработка либо вернёт внутренний элемент, либо вызовет panic.
Обратите внимание, что можно вручную настроить сообщение выдаваемое при панике с помощью expect, в противном случае unwrap оставляет нам менее понятный вывод, чем явная обработка. В следующем примере явная обработка даёт более контролируемый результат, при этом сохраняется возможность паниковать, если это необходимо.
// Взрослый человек всё это видео, и может хорошо справиться с любым напитком. // Все напитки обрабатываются явно, с использованием конструкции `match`. fn give_adult(drink: Option<&str>) { // выдать взрослому напиток // Укажем что нужно делать, в каждом случае. match drink { Some("лимонад") => println!("Фи! Слишком сладко."), Some(inner) => println!("{}? Хорошо.", inner), None => println!("Нет напитка? Ну что ж."), } } // Другие будут паниковать перед тем как выпить напитки, содержащие сахар. // Все напитки обрабатываются неявно, с использованием `unwrap`. fn drink(drink: Option<&str>) { // `unwrap` возвращает `panic` когда получает на вход `None`. let inside = drink.unwrap(); if inside == "лимонад" { panic!("AAAaaaaa!!!!"); } println!("Я люблю {}ы!!!!!", inside); } fn main() { let water = Some("вода"); let lemonade = Some("лимонад"); let void = None; give_adult(water); give_adult(lemonade); give_adult(void); let coffee = Some("кофе"); let nothing = None; drink(coffee); drink(nothing); }