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); }