Паника в предыдущем примере делает код ненадёжным. Обычно, мы хотим вернуть ошибку вызывающей стороне, чтобы уже она решала, как с ней поступить.
Первое, что нам нужно знать - это с каким типом ошибки мы работаем. Для определения типа Err, мы посмотрим на parse(), реализованную с типажом FromStr для i32. В результате, тип Err указан как ParseIntError.
В примере ниже, простой match делает код более громоздким.
use std::num::ParseIntError;
// Мы используем сопоставление с образцом без `unwrap()` и меняем тип результата.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result {
match first_number_str.parse::() {
Ok(first_number) => {
match second_number_str.parse::() {
Ok(second_number) => {
Ok(first_number * second_number)
},
Err(e) => Err(e),
}
},
Err(e) => Err(e),
}
}
fn print(result: Result) {
match result {
Ok(n) => println!("n равно {}", n),
Err(e) => println!("Ошибка: {}", e),
}
}
fn main() {
// Это даёт разумный ответ.
let twenty = multiply("10", "2");
print(twenty);
// Следующее теперь предоставляет более понятное сообщение об ошибке.
let tt = multiply("t", "2");
print(tt);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
К счастью, map, and_then многие другие комбинаторы Option также реализованы и для Result. Документация по Result содержит полный их список.
use std::num::ParseIntError;
// Как и с `Option`, мы можем использовать комбинаторы, как `map()`.
// Эта функция в основном идентична предыдущей и читается как:
// изменяем n при валидном значении, иначе передаём ошибку.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result {
first_number_str.parse::().and_then(|first_number| {
second_number_str.parse::().map(|second_number| first_number * second_number)
})
}
fn print(result: Result) {
match result {
Ok(n) => println!("n равно {}", n),
Err(e) => println!("Ошибка: {}", e),
}
}
fn main() {
// Это даёт разумный ответ.
let twenty = multiply("10", "2");
print(twenty);
// Следующее теперь предоставляет более понятное сообщение об ошибке.
let tt = multiply("t", "2");
print(tt);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX