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

为何Sized trait无法被转化为trait object?

为什么Sized超trait会阻止trait被用作trait object?

问题背景

当我们定义一个无约束的trait时,代码可以正常编译:

trait Trait {}

struct Foo {}
impl Trait for Foo {}

fn do_work(_: &dyn Trait) {}

但如果为Trait添加Sized作为超trait:

trait Trait: Sized {}

编译会失败并抛出如下错误:

error[E0038]: the trait `Trait` cannot be made into an object
 --> src\main.rs:6:16
  |
6 | fn do_work(_: &dyn Trait) {}
  |                ^^^^^^^^^ `Trait` cannot be made into an object
  |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 --> src\main.rs:1:14
  |
1 | trait Trait: Sized {}
  |       -----  ^^^^^ ...because it requires `Self: Sized`

已知Sized超trait会破坏对象安全性,但不理解背后逻辑,特此请教:为何Sized超trait会阻止trait被用作trait object?

解答

  • Sized trait的核心作用是标记编译时大小已知的类型。当你把Sized设为超trait时,不仅要求所有实现该trait的类型必须是Sized,更关键的是这个约束会直接作用于trait object本身。
  • trait object(比如dyn Trait)是动态类型的载体,它可以指向任意实现了Trait的类型实例——不同实例的大小可能完全不同,因此trait object本身的大小在编译时是无法确定的,属于非Sized类型。
  • 当你要求trait必须继承Sized时,就等同于强制要求trait object满足Sized约束,但这和trait object的动态特性完全矛盾。编译器为了避免这种逻辑冲突,会直接报错禁止将该trait构造成对象。

总结来说:Sized要求类型大小编译时可知,而trait object是动态大小类型,两者本质不兼容,因此添加Sized超trait会直接破坏trait的对象安全性。

内容的提问来源于Stack Exchange,提问作者aedm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:41:29