我正在尝试实现一个简单的模式:如果我有一些错误,我可以尝试恢复我的应用程序,否则我只是将此异常弹出给调用者:
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
有效期......
答案 0 :(得分:3)
确实,编译器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
用法的一些问题。
答案 1 :(得分:2)
因为那是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,除非您使用自定义错误变体。
另见: