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