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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:05:20