Выбрать главу

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() могут быть связаны друг с другом в цепочку.