我有一个正在尝试遍历的错误链接列表。给定MyError,它是带有可选代码的错误链接列表,我的目标是遍历该链并返回第一个非None代码:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误:
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
Run Code Online (Sandbox Code Playgroud)
我不确定为什么这里会出现生命周期错误,因为源函数返回一个静态特征对象(这意味着该对象后面没有其他引用,对吧?)。
&source as &dyn Any不按你的想法做。source类型为&(dyn std::error::Error + Send + Sync + 'static),因此必须擦除该类型才能强制转换&source为&dyn Any。
该+ 'static类型中的 仅仅意味着被引用的类型(实现 的类型Error + Send + Sync)必须不包含非'static引用。still&有自己的生命周期,但它不是'static(也不可能有,因为它是从 借用的self)。正是该引用的生命周期阻止&(dyn std::error::Error + Send + Sync + 'static)了'static.
你想做的是source as &dyn Any,如果它有效的话,将会升级dyn Error到dyn Any。但这是不可能的,因为Any不是 的超特征Error。此外,即使确实Error有Any作为超级特征,Rust 目前也不支持这样的强制转换。
特征升级可在每晚的功能标志下使用,但您不需要它。使用自身downcast定义的方法dyn Error,添加这些方法是为了支持此用例。
if let Some(myerr) = source.downcast_ref::<MyError>() {
return myerr.traverse();
}
Run Code Online (Sandbox Code Playgroud)
如果您需要向下转换一个不是的特征对象dyn Error,您将需要找到一个解决方法。
| 归档时间: |
|
| 查看次数: |
397 次 |
| 最近记录: |