Уроки модуля (2/2)
Сопоставление с образцом, параметр и результат
В Rust имеется чрезвычайно мощный механизм потока управления, называемый сопоставлением шаблонов. Он позволяет сравнивать значение с рядом шаблонов и выполнять код на основе того, какой шаблон соответствует.
Заявление match
Оператор match в Rust похож на оператор switch в других языках, но гораздо более мощный и безопасный. Компилятор гарантирует, что совпадение является полным, то есть должны быть обработаны все возможные случаи:
enum Direction {
North,
South,
East,
West,
}
let dir = Direction::East;
match dir {
Direction::North => println!("Andiamo a Nord"),
Direction::South => println!("Andiamo a Sud"),
Direction::East => println!("Andiamo a Est"),
Direction::West => println!("Andiamo a Ovest"),
}Обработка отсутствия значения: Option
В Rust нет понятия нулевого значения (null или nil). Вместо этого стандартная библиотека определяет перечисление Option<T>, которое может содержать:
Some(T): содержит значение типаT.None: указывает на отсутствие значения.
let x: Option<i32> = Some(5);
let y: Option<i32> = None;
match x {
Some(val) => println!("C'e un valore: {}", val),
None => println!("Nessun valore trovato"),
}Обработка исправимых ошибок: Result
Для операций, которые могут завершиться неудачно (например, чтение файла или преобразование строки в число), Rust использует перечисление Result<T, E>, которое имеет два варианта:
Ok(T): операция завершилась успешно и содержит значение успехаT.Err(E): операция не удалась и содержит ошибкуE.
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err(String::from("Divisione per zero!"))
} else {
Ok(numerator / denominator)
}
}Благодаря компилятору Rust вам придется обрабатывать случай Err, прежде чем вы сможете получить доступ к значению внутри Ok, что предотвращает множество распространенных ошибок во время выполнения.
Шаблон подстановочного знака _
При работе с типами данных, имеющими большое количество вариантов (например, целыми числами), перечисление всех случаев в match невозможно. Rust позволяет использовать подстановочный знак _ для перехвата всех оставшихся случаев, которые не определены явно:
let some_u8 = 3u8;
match some_u8 {
1 => println!("One"),
2 => println!("Two"),
_ => println!("Something else"), // Handles all other values
}Попробуйте сами
Объявите переменную с именем Maybe_value типа Option<i32>, содержащую Some(42). Используйте оператор сопоставления для may_value: если он содержит Some(v), выведите «значение: v» (используя println!), если он содержит None, выведите «нет значения».
Показать подсказку
Напишите блок `match may_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.
Решение доступно после 3 попыток
Завершите функцию check_age так, чтобы она возвращала Ok('Adult'), если возраст больше или равен 18, и Err('Minor') в противном случае.
Показать подсказку
Используйте `if age >= 18`, чтобы решить, следует ли возвращать `Ok('Adult')`или`Err('Minor')`.
Решение доступно после 3 попыток
Объявите перечисление с именем Status, содержащее варианты Active и Inactive. В файле main объявите переменную current_status со значением Status::Active. Наконец, используйте оператор сопоставления для current_status, чтобы напечатать «активный», если статус «Активный», или «неактивный», если статус «Неактивный».
Показать подсказку
Определите перечисление перед основным с помощью `enum Status { Active, Inactive }`. В основном используйте `let current_status = Status::Active;` и выполните`match` для вариантов.
Решение доступно после 3 попыток