我有一个错误的链接列表,我正在try 遍历这些错误.

type BoxedError = Box<dyn std::error::Error + Send + Sync + 'static>;

#[derive(Debug)]
struct MyError {
    code: Option<u32>,
    source: Option<BoxedError>,
}

impl std::error::Error for MyError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        self.source().map(|s| s as _)
    }
}

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Display::fmt("", f)
    }
}

impl MyError {
    fn source(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
        self.source.as_ref().map(|c| c.as_ref())
    }

    fn traverse(&self) -> Option<u32> {
        use core::any::Any;
        if let Some(code) = self.code {
            return Some(code);
        }    
        if let Some(source) = self.source() {
            let as_any = &source as &dyn Any;
            if let Some(myerr) = as_any.downcast_ref::<MyError>() {
                return myerr.traverse();
            }
        }
        None
    }
}

这会产生以下错误:

error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
  --> src/lib.rs:31:36
   |
26 |     fn traverse(&self) -> Option<u32> {
   |                 ----- this data with an anonymous lifetime `'_`...
...
31 |         if let Some(source) = self.source() {
   |                               ---- ^^^^^^
   |                               |
   |                               ...is used here...
32 |             let as_any = &source as &dyn Any;
   |                          ------- ...and is required to live as long as `'static` here

For more information about this error, try `rustc --explain E0759`.
error: could not compile `playground` due to previous error

考虑到源函数返回一个静态trait对象(这意味着该对象后面没有其他引用,对吗?),我不知道为什么会出现终身错误.

推荐答案

&source as &dyn Any并不是你想的那样.source的类型为&(dyn std::error::Error + Send + Sync + 'static),因此必须擦除该类型才能将&source强制为&dyn Any.

此类型中的+ 'static仅意味着实现Error + Send + Syncreferenced类型必须不包含非'static引用.&仍然有自己的生命周期 ,不是'static(也不能是'static,因为它是从self借来的).正是该引用的生存期阻止了&(dyn std::error::Error + Send + Sync + 'static)成为'static.

你想做的是source as &dyn Any,如果它起作用的话,会把dyn Error调高到dyn Any.但这是不可能的,因为Any不是Error的超级性状.此外,即使Error确实有Any个超性状,Rust doesn't currently support such a cast个.

特征向上转换在夜间功能标志下可用,但您不需要.使用dyn Error本身定义的downcast个方法,这些方法是为了支持此用例而添加的.

if let Some(myerr) = source.downcast_ref::<MyError>() {
    return myerr.traverse();
}

如果需要向下转换不是dyn Error的trait对象,则需要找到workaround.

Rust相关问答推荐

如何初始化match声明中的两个变量而不会激怒borrow 判断器?

什么样的 struct 可以避免使用RefCell?

如何使用 list 在Rust for Windows中编译?

为什么铁 rust S似乎有内在的易变性?

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

铁 rust ,我的模块介绍突然遇到了一个问题

如何使用reqwest进行异步请求?

如何将带有嵌套borrow /NLL 的 Rust 代码提取到函数中

使用占位符获取用户输入

如何处理闭包中的生命周期以及作为参数和返回类型的闭包?

sha256 摘要仅适用于 &*

将引用移动到线程中

面临意外的未对齐指针取消引用:地址必须是 0x8 的倍数,但为 0x__错误

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

如何递归传递闭包作为参数?

Rust 中 `Option` 的内存开销不是常量

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?

如何存储返回 Future 的闭包列表并在 Rust 中的线程之间共享它?

如何为返回正确类型的枚举实现 get 方法?

相互调用的递归异步函数:检测到循环