如何声明含可选dyn Error字段的Rust结构体?
问题:Rust结构体声明含
dyn Error字段时触发编译错误E0277 尝试声明如下结构体:
use std::{error}; pub struct AppError { msg: Option<String>, // error: Option<anyhow::Error>, // 此写法可行 error: Option<dyn error::Error + Send + Sync + 'static>, // 需使用该写法而非anyhow }
编译时报错:
error[E0277]: the size for values of type `(dyn std::error::Error + Send + Sync + 'static)` cannot be known at compilation time --> src/lib.rs:6:10 | 6 | error: Option<dyn error::Error + Send + Sync + 'static>, // but I need this, not anyhow | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn std::error::Error + Send + Sync + 'static)` note: required by a bound in `Option` For more information about this error, try `rustc --explain E0277`.
修复方案
错误核心原因是:dyn error::Error + Send + Sync + 'static属于无大小类型(Unsized Type),而Option<T>要求泛型参数T必须实现Sized trait(即编译期可确定大小)。要解决这个问题,需要用指针类型包裹该 trait 对象,将其转换为大小固定的类型。
最常用的方案是使用Box智能指针,修改后的结构体如下:
use std::error; pub struct AppError { msg: Option<String>, error: Option<Box<dyn error::Error + Send + Sync + 'static>>, }
Box<dyn ...>是大小固定的指针类型(64位系统占8字节),完全满足Option对Sized的要求,编译可直接通过。
如果有特殊场景需求,也可以根据情况选择其他指针类型:
- 若需要多所有权共享,可使用
Rc<dyn ...> - 若需要跨线程安全共享,可使用
Arc<dyn ...>,示例如下:
use std::{error, sync::Arc}; pub struct AppError { msg: Option<String>, error: Option<Arc<dyn error::Error + Send + Sync + 'static>>, }
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

