You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中打印&dyn Error背后的实际类型

实现获取&dyn Error实际类型的函数

你可以通过Rust标准库中的std::any::type_name_of_val函数,直接获取&dyn Error背后的实际类型名称,结合source()方法返回的'static约束,完成format_type_of的实现:

完整代码示例

use std::any::type_name_of_val;
use std::error::Error;
use std::fmt;

// 获取错误实际类型的函数
fn format_type_of(e: &(dyn Error + 'static)) -> String {
    type_name_of_val(e).to_string()
}

fn error_chain_fmt(
    e: &impl Error,
    f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
    writeln!(f, "{}\n", e)?;
    let mut current = e.source();
    while let Some(cause) = current {
        writeln!(f, "Caused by: ({}) \n\t{}", format_type_of(cause), cause)?;
        current = cause.source();
    }
    Ok(())
}

// 自定义错误示例
#[derive(Debug)]
struct MyError {
    source: Option<Box<dyn Error + 'static>>,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "My custom error occurred")
    }
}

impl Error for MyError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        self.source.as_deref()
    }
}

// 使用示例
fn main() -> Result<(), MyError> {
    let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "no access");
    let my_error = MyError {
        source: Some(Box::new(io_error)),
    };
    
    eprintln!("{}", my_error);
    Ok(())
}

关键说明

  1. type_name_of_val的作用:该函数会返回传入值的具体类型字符串,对于&dyn Error引用,它会解析到底层的实际类型(比如示例中的std::io::Error)。
  2. 'static约束:由于Error trait的source()方法返回的是&(dyn Error + 'static),我们可以安全地使用type_name_of_val——只有拥有'static生命周期的类型才能被正确识别具体类型。
  3. 输出效果:运行示例后,错误链会展示为:
    My custom error occurred
    
    Caused by: (std::io::Error) 
         Permission denied (os error 13)
    

内容的提问来源于stack exchange,提问作者Ievgen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 03:59:58