介绍 ?
有时候我们只是想要 unwrap
的简洁性,而又不想出现 panic
的可能性。直到现在,当我们真正想把变量取出时,unwrap
迫使我们进行越来越深的嵌套。这正是 ?
的目的。
当找到一个 Err
时,有两种有效的操作可以执行:
panic!
,我们已经决定尽可能避免使用它return
,因为Err
意味着它无法被处理
?
*几乎*1 完全等同于 unwrap
,只是在遇到 Err
时会 return
而不是 panic
。让我们看看如何简化之前使用组合器的示例。
use std::num::ParseIntError; fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> { let first_number = first_number_str.parse::<i32>()?; let second_number = second_number_str.parse::<i32>()?; Ok(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() { print(multiply("10", "2")); print(multiply("t", "2")); }
try!
宏
在 ?
出现之前,相同的功能是通过 try!
宏实现的。现在推荐使用 ?
运算符,但在查看旧代码时,您可能仍然会发现 try!
。上一个示例中的相同的 multiply
函数使用 try!
会是这样:
// To compile and run this example without errors, while using Cargo, change the value // of the `edition` field, in the `[package]` section of the `Cargo.toml` file, to "2015". use std::num::ParseIntError; fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> { let first_number = try!(first_number_str.parse::<i32>()); let second_number = try!(second_number_str.parse::<i32>()); Ok(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() { print(multiply("10", "2")); print(multiply("t", "2")); }
1
有关更多详细信息,请参见 重新进入 ?。