Result
的 map
方法
在上一个例子中,multiply
函数中的恐慌处理并不能保证代码的健壮性。通常,我们希望将错误返回给调用者,以便它能够决定如何正确地响应错误。
我们首先需要知道我们正在处理哪种类型的错误。为了确定 Err
类型,我们查看 parse()
,它是用 FromStr
trait 为 i32
实现的。因此,Err
类型被指定为 ParseIntError
。
在下面的例子中,直接使用 match
语句会导致代码整体上更加繁琐。
use std::num::ParseIntError; // With the return type rewritten, we use pattern matching without `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 is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { // This still presents a reasonable answer. let twenty = multiply("10", "2"); print(twenty); // The following now provides a much more helpful error message. let tt = multiply("t", "2"); print(tt); }
幸运的是,Option
的 map
、and_then
以及许多其他组合器也为 Result
实现了。您可以在 Result
中找到完整的列表。
use std::num::ParseIntError; // As with `Option`, we can use combinators such as `map()`. // This function is otherwise identical to the one above and reads: // Multiply if both values can be parsed from str, otherwise pass on the error. 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 is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { // This still presents a reasonable answer. let twenty = multiply("10", "2"); print(twenty); // The following now provides a much more helpful error message. let tt = multiply("t", "2"); print(tt); }