Модульні уроки (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). Використовуйте оператор відповідності для maybe_value: якщо він містить Some(v), надрукуйте «value is: v» (використовуючи println!), якщо він містить None, надрукуйте «no value».
Показати підказку
Напишіть блок `match maybe_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, щоб надрукувати «active», якщо статус «Active», або «inactive», якщо статус «Inactive».
Показати підказку
Визначте перелік перед основним за допомогою `enum Status { Active, Inactive }`. У основному використовуйте `let current_status = Status::Active;`і виконайте`збіг` варіантів.
Рішення доступне після 3 спроб