Rust中Box化dyn Getter trait对象遇大小未知错误的解决求助
Rust E0277错误:dyn Getter大小无法确定的解决方法
错误原因分析
你遇到的error[E0277]: 类型dyn Getter的值大小在编译时无法确定,核心问题出在impl<T: Getter> Getter for &T这个实现上。Rust中泛型参数默认隐含Sized约束,该实现仅覆盖了T为固定大小类型的情况,但dyn Getter是动态大小类型(DST),不满足Sized,因此&dyn Getter并没有自动实现Getter trait。
而MapGetter<T,F>实现Getter的前提是T: Getter,当你将source设为&dyn Getter时,编译器检查发现&dyn Getter不满足Getter约束,最终导致无法将MapGetter转换为Box<dyn Getter> trait对象。
解决方法
1. 修改引用类型的Getter实现
调整&T的Getter实现,添加?Sized约束,允许T为动态大小类型:
impl<T: Getter + ?Sized> Getter for &T { fn compute(&self) -> i32 { (**self).compute() } }
?Sized表示T可以是固定大小或动态大小类型,这样&dyn Getter就能满足约束,获得Getter实现。
2. 修复返回值语法错误
apply方法中Box::new(...)末尾多了分号,导致没有返回值,需要去掉分号:
fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a> { Box::new(MapGetter { source: a, f: |n:i32| n + 5 }) }
完整修正代码
trait Getter { fn compute(&self) -> i32; fn pipe(&self, operator: &dyn Operator) -> Box<dyn Getter> where Self: Sized, { operator.apply(&self) } } impl<T: Getter + ?Sized> Getter for &T { fn compute(&self) -> i32 { (**self).compute() } } impl<T: Getter> Getter for Box<T> { fn compute(&self) -> i32 { (*self).compute() } } struct PureGetter<T>(T); impl Getter for PureGetter<i32> { fn compute(&self) -> i32 { self.0 } } struct MapGetter<T, F> { source: T, f: F, } impl<T, F> Getter for MapGetter<T, F> where T: Getter, F: FnMut(i32) -> i32 + Clone, { fn compute(&self) -> i32 { (self.f.clone())(self.source.compute()) } } trait Operator { fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a>; } struct PlusFive; impl Operator for PlusFive { fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a> { Box::new(MapGetter { source: a, f: |n:i32| n + 5 }) } } fn main() { let result = PureGetter(0).pipe(&PlusFive).compute(); println!("{:#?}", result); }
编译运行后会输出5,符合预期。
补充说明
该方案完全满足你的动态分发需求:dyn Operator列表可正常工作,每个Operator作为独立逻辑片段,能多次应用到不同的Getter实例上。
内容的提问来源于stack exchange,提问作者Mrk Sef
相关产品推荐
相关产品推荐

