为什么使用 Self 作为类型参数时需要 Sized?

Why is Sized required when using Self as a type parameter?

我正在研究 traits,发现在使用 Self 作为类型参数时需要 Sized

trait Foo: Sized { // does not compile without Sized
    type Bar: Baz<F = Self>; 
    type Quiz: Qux<Self>
}

trait Baz {
    type F: Foo;
}

trait Qux<F: Foo> {}

为什么 Sized 对于 Self 很重要?为什么需要明确指定,在这种情况下不 Sized 类型有什么问题?

对于类型参数和关联类型,有一个默认设置的隐式 Sized 特征边界。所以这些是等价的:

trait Baz {
    type F: Foo;
}

trait Qux<F: Foo> { }
trait Baz {
    type F: Foo + Sized;
}

trait Qux<F: Foo + Sized> { }

对于这两个特征,默认情况下需要 F 调整大小。因此,当您尝试在 Foo 特征中使用它们时,这意味着 Foo 也需要调整大小。

要允许大小不一的类型,显式添加 ?Sized 特性绑定以选择退出默认行为:

trait Baz {
    type F: Foo + ?Sized;
}

trait Qux<F: Foo + ?Sized> { }

这允许编译而不需要 Sized:

trait Foo {
    type Bar: Baz<F = Self>; 
    type Quiz: Qux<Self>;
}