我正在阅读以下文档File:
//..
let mut file = File::create("foo.txt")?;
//..
Run Code Online (Sandbox Code Playgroud)
什么是?在这条线?我不记得以前在Rust Book中看过它了.
Mat*_* M. 96
您可能已经注意到,Rust没有例外.它有恐慌,但它们的功能有限(它们不能携带结构化信息),并且不鼓励它们用于错误处理(它们用于不可恢复的错误).
在Rust中,错误处理使用Result.一个典型的例子是:
fn halves_if_even(i: i32) -> Result<i32, Error> {
if i % 2 == 0 { Ok(i/2) } else { Err(/* something */) }
}
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = match halves_if_even(i) {
Ok(i) => i,
e => return e,
};
// use `i`
}
Run Code Online (Sandbox Code Playgroud)
这很棒,因为:
然而,它并不理想,因为它非常冗长.这就是问号运算符的?用武之地.
以上可以改写为:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
Run Code Online (Sandbox Code Playgroud)
这更简洁.
是什么?在这里所做的相当于match上述表示的.简而言之:它解压缩Resultif if并返回错误,如果没有.
这有点神奇,但错误处理需要一些魔法来减少样板,并且与异常不同,它可以立即看到哪些函数调用可能会或可能不会出错:那些装饰的?.
也可以看看:
snn*_*snn 28
它是一个解包Result<T, E>和Option<T>值的后缀运算符。
如果应用于Result<T, E>,它会解开结果并为您提供内部值,从而将错误传播到调用函数。
let number = "42".parse::<i32>()?;
println!("{:?}", number); // 42
Run Code Online (Sandbox Code Playgroud)
当应用于 an 时Option<T>,它会传播None到调用者,让您处理 Some 分支的内容。
let val = Some(42)?;
println!("{:?}", val); // 42
Run Code Online (Sandbox Code Playgroud)
该?运算符只能在返回的函数中使用Result,Option如下所示:
use std::num::ParseIntError;
fn main() -> Result<(), ParseIntError> {
let number = "42".parse::<i32>()?;
println!("{:?}", number);
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
这是 Rust 提供的便利,它消除了样板代码并使函数的实现更简单。
Yil*_*maz 12
它用于propagating errors. 有时我们编写的代码可能会失败,但我们不想立即捕获并处理错误。如果您有太多代码来处理每个地方的错误,您的代码将不可读。相反,如果发生错误,我们可能想让调用者处理它。我们希望错误在调用堆栈中向上传播。
// file type is Result if "?" is not used
// file:Result<File,Error>
let mut file = File::create("foo.txt");
// file type is File if "?" is used
// file:File
let mut file = File::create("foo.txt")?;
// if an error occurs, code after this line will not be executed
// function will return the error
// if we do not return here, the program will continue execution even though an error occurred. This could lead to unexpected behavior or incorrect results.
Run Code Online (Sandbox Code Playgroud)
的行为?取决于该函数返回成功结果还是错误结果:
filefile。函数将错误返回给调用者使用?与此代码相同的方法
let mut file = match File::create("foo.txt") {
Err(why) => panic!("couldn't create {}: {}", display, why),
Ok(file) => file,
};
Run Code Online (Sandbox Code Playgroud)
?对于 Option 类型也有类似的作用。在返回 Option 的函数中,您可以使用 ? 在 None 的情况下解包值并提前返回: