我正在尝试实现一个简单的模式:如果我有一些错误,我可以尝试恢复我的应用程序,否则我只是将此异常弹出给调用者:
use std::error::Error;
fn main() {
let _ = sample();
}
fn sample() -> std::result::Result<i32, std::io::Error> {
let result: Result<i32, std::io::Error> = Ok(10); // performing some operation
match result {
Ok(x) => Ok(x + 1),
Err(e) => match e.cause() {
// if it has any error
Some(cause) => {
// and it has any cause
let io_error = cause.downcast_ref::<std::io::Error>(); // and this cause is IO error
match io_error {
Some(_) => Ok(547), // return default value
None => Err(e), // otherwise return an error
}
}
None => Err(e),
},
}
}
如果操作成功,我想返回x+1
。如果没有,但它是由io::Error
引起然后返回547
。如果它是由其他东西引起的,只需按原样返回错误。
当前的编译器错误是:
error[E0597]: `e` does not live long enough
--> src\main.rs:11:25
|
11 | Err(e) => match e.cause() { // if it's caused
| ^ borrowed value does not live long enough
...
21 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
我不明白为什么它说它必须有static
一生......
确实,编译器is not more explicit是不幸的。
让我放松一下:
Error::downcast_ref
仅适用于Error + 'static
(因此,当self
的生命本身为'static
时),cause.downcast_ref
,cause
必须是'static
,Error::cause
将其结果的生命周期与self
的结果联系起来,e.cause()
,e
必须是'static
,e
是在Err(e)
临时引入的。希望这更清楚。
我还没有使用它,但Rust核心团队成员之一(无船)一直在研究新的failure
crate,据说可以解决Error
用法的一些问题。
因为这是一个requirement of the function you are using:
impl Error + 'static {
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T>
}
你不能低估非'static
的特征对象。
可以进一步减少示例代码以使其更加清晰。注释掉downcast_ref
允许编译代码:
fn example(result: Result<i32, std::io::Error>) -> Result<i32, std::io::Error> {
let e = result.unwrap_err();
let cause = e.cause().unwrap();
let _io_error = cause.downcast_ref::<std::io::Error>();
unimplemented!()
}
这可能只是你缩减的示例代码的工件,但我不明白你为什么采取Result<_, std::io::Error>
并检查io::Error
的原因是否是另一个io::Error
。如果你的Result
是一个Err
,那么你知道这是一个io:Error
,因为它是唯一可能的事情。 io::Error
doesn't even provide a cause,除非您使用自定义错误变体。
也可以看看: