我正在阅读the documentation for File
:
//..
let mut file = File::create("foo.txt")?;
//..
这一行中的?
是多少?我不记得以前在Rust Book中看过它了。
答案 0 :(得分:75)
您可能已经注意到,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`
}
这很棒,因为:
?
的用武之地。
以上内容可以改写为:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
更简洁。
此处?
的作用相当于上面的match
声明。简而言之:如果没有,它会解包Result
,如果没有,返回错误。
这有点神奇,但是错误处理需要一些魔法来减少样板,并且与异常不同的是,可以立即看到哪些函数调用可能会或可能不会错误:那些用?
装饰的。
另见:
答案 1 :(得分:2)
它用于可传播错误类型Result
不处理错误情况,而是将其传播到调用者代码,仅处理确定情况。好处是,它消除了很多样板并简化了功能的实现。