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