Result
Result — це більш багата версія типу Option, яка
описує можливу помилку замість можливої відсутності.
Тобто, Result<T, E> може мати один із двох результатів:
Ok(T): ЕлементTбуло знайденоErr(E): Було знайдено помилку з елементомE
За домовленістю, очікуваний результат — Ok, тоді як неочікуваний результат — Err.
Як і Option, Result має багато пов’язаних із ним методів. unwrap(), наприклад,
або повертає елемент T, або викликає panic. Для обробки випадків
існує багато комбінацій між Result і Option, які перекриваються.
Під час роботи з Rust ви, ймовірно, зіткнетеся з методами, що повертають
тип Result, наприклад методом parse(). Не завжди може бути
можливим розібрати рядок у інший тип, тому parse() повертає
Result, що вказує на можливу невдачу.
Подивімося, що відбувається, коли ми успішно та неуспішно викликаємо parse() для рядка:
fn multiply(first_number_str: &str, second_number_str: &str) -> i32 {
// Let's try using `unwrap()` to get the number out. Will it bite us?
let first_number = first_number_str.parse::<i32>().unwrap();
let second_number = second_number_str.parse::<i32>().unwrap();
first_number * second_number
}
fn main() {
let twenty = multiply("10", "2");
println!("double is {}", twenty);
let tt = multiply("t", "2");
println!("double is {}", tt);
}
У неуспішному випадку parse() залишає нас із помилкою, на якій unwrap()
може викликати panic. Крім того, panic завершує нашу програму і виводить
неприємне повідомлення про помилку.
Щоб поліпшити якість нашого повідомлення про помилку, нам слід точніше вказати тип повернення і розглянути можливість явної обробки помилки.
Використання Result у main
Тип Result також може бути типом повернення функції main, якщо
це явно вказано. Зазвичай функція main має такий вигляд:
fn main() {
println!("Hello World!");
}
Однак main також може мати тип повернення Result. Якщо в
межах функції main виникає помилка, вона поверне код помилки і виведе
debug-представлення помилки (використовуючи трейт Debug). Наведений нижче
приклад показує таку ситуацію і торкається аспектів, які розглядаються в [наступному розділі].
use std::num::ParseIntError;
fn main() -> Result<(), ParseIntError> {
let number_str = "10";
let number = match number_str.parse::<i32>() {
Ok(number) => number,
Err(e) => return Err(e),
};
println!("{}", number);
Ok(())
}