结果
Result
是 Option
类型的一个更丰富的版本,它描述了可能的*错误*而不是可能的*缺失*。
也就是说,Result<T, E>
可能有两个结果之一
Ok(T)
:找到了元素T
Err(E)
:找到元素E
时出错
按照惯例,预期结果是 Ok
,而意外结果是 Err
。
与 Option
类似,Result
有许多与之关联的方法。例如,unwrap()
要么产生元素 T
,要么 panic
。对于情况处理,Result
和 Option
之间有许多重叠的组合器。
在使用 Rust 时,您可能会遇到返回 Result
类型的方法,例如 parse()
方法。可能并非总能将字符串解析为其他类型,因此 parse()
返回一个 Result
,指示可能出现的失败。
让我们看看成功和不成功地 parse()
一个字符串时会发生什么
fn multiply(first_number_str: &str, second_number_str: &str) -> i32 { // Let's try using `unwrap()` to get the number out. Will it bite us? let first_number = first_number_str.parse::<i32>().unwrap(); let second_number = second_number_str.parse::<i32>().unwrap(); first_number * second_number } fn main() { let twenty = multiply("10", "2"); println!("double is {}", twenty); let tt = multiply("t", "2"); println!("double is {}", tt); }
在不成功的情况下,parse()
会给我们留下一个错误,供 unwrap()
在其上 panic
。此外,panic
会退出我们的程序并提供一条令人不快的错误消息。
为了提高错误消息的质量,我们应该更具体地说明返回类型,并考虑显式处理错误。
在 main
中使用 Result
如果显式指定,Result
类型也可以是 main
函数的返回类型。通常,main
函数的形式如下
fn main() { println!("Hello World!"); }
但是,main
也可以具有 Result
的返回类型。如果在 main
函数中发生错误,它将返回一个错误代码并打印错误的调试表示(使用 Debug
特征)。以下示例展示了这种情况,并涉及了下一节中涵盖的方面。
use std::num::ParseIntError; fn main() -> Result<(), ParseIntError> { let number_str = "10"; let number = match number_str.parse::<i32>() { Ok(number) => number, Err(e) => return Err(e), }; println!("{}", number); Ok(()) }