如何在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(()) }
关键说明
type_name_of_val的作用:该函数会返回传入值的具体类型字符串,对于&dyn Error引用,它会解析到底层的实际类型(比如示例中的std::io::Error)。'static约束:由于Errortrait的source()方法返回的是&(dyn Error + 'static),我们可以安全地使用type_name_of_val——只有拥有'static生命周期的类型才能被正确识别具体类型。- 输出效果:运行示例后,错误链会展示为:
My custom error occurred Caused by: (std::io::Error) Permission denied (os error 13)
内容的提问来源于stack exchange,提问作者Ievgen
相关产品推荐
相关产品推荐

