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

Rust中如何从trait对象的函数返回动态类型值?

Rust 动态 trait 对象编译错误解决

问题代码

trait A {}

trait B {
    type C: A;
    fn foo(self) -> Self::C;
}

fn process(b: Box<dyn B<C = dyn A>>) -> Box<dyn A> {
    Box::new(b.foo())
}

错误信息

error[E0277]: 无法在编译时确定类型 `(dyn A + 'static)` 的大小
 --> tests/test.rs:9:16
  |
9 |     Box::new(b.foo())
  |                ^^^ 编译时无法确定大小
  |
  = help: 特征 `Sized` 未为 `(dyn A + 'static)` 实现

问题原因

dyn A 是动态大小类型(DST),而 foo 方法返回的 Self::C 在这里被指定为 dyn A。但 Rust 里函数返回值默认要求是大小确定的类型(实现 Sized trait),Box::new 也需要接收一个编译时大小已知的值,直接返回 dyn A 不符合要求,因为编译器没法知道它的具体大小。

解决方法

有两种常见的修复思路:

方案一:让 foo 直接返回装箱后的 trait 对象

把 foo 的返回类型改成 Box<dyn A>,这样就不需要关联类型直接对应 dyn A:

trait A {}

trait B {
    fn foo(self) -> Box<dyn A>;
}

fn process(b: Box<dyn B>) -> Box<dyn A> {
    b.foo()
}

方案二:允许关联类型是动态大小类型

给关联类型加上 ?Sized 约束,同时让 foo 返回 Box<Self::C>,用装箱来包裹动态大小的类型:

trait A {}

trait B {
    type C: A + ?Sized; // 允许关联类型是动态大小类型
    fn foo(self) -> Box<Self::C>;
}

fn process(b: Box<dyn B<C = dyn A>>) -> Box<dyn A> {
    b.foo()
}

核心要点

  • 动态 trait 对象(dyn Trait)属于动态大小类型,不能直接作为函数返回值,必须用指针、装箱这类方式包裹
  • Sized 是 Rust 默认的 trait 约束,函数返回值默认要求实现该 trait,如果要支持动态大小类型,需要显式标注 ?Sized

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:07:14