为什么即使从未使用过关联类型,这里也需要它?
trait Tr {
type Ty;
fn go(&self) -> () {}
}
fn foo(t: dyn Tr) -> () {
t.go()
}
我明白了
2 | type Ty;
| -------- `Ty` defined here
...
6 | fn foo(t: dyn Tr) -> () {
| ^^^^^^ associated type `Ty` must be specified
答案 0 :(得分:1)
您正在制作特征对象,并且特征对象的要求是指定所有关联的类型。您的情况非常简单,并且特征的方法不使用关联的类型,但是object safety rules是为更一般的情况设计的。
如果您只是使用受Tr
约束的类型参数,则无需指定关联的类型:
fn foo<T: Tr>(t: T) -> () {
t.go()
}
这是因为可以为调用T
的每个foo
推断关联的类型。
如果特征对象被允许具有未指定的关联类型,则函数内的代码将无法推断出它。在这种情况下,您可能会争辩说,这仅应限制该函数的作用,但是为特征对象类型的定义给出了对象安全规则,无论其实际使用方式如何。这使得考虑起来更简单,因为在某些情况下不会使用trait对象,而在其他情况下则无法使用。
顺便说一句,即使您在函数签名中为对象指定了关联的类型,也必须通过引用或框将其传递给对象,例如:
fn foo(t: &dyn Tr<Ty = SomeType>) -> () {
t.go()
}
这是因为trait对象的大小在编译时未知。取而代之的是,您需要将它们放在参考之后,该参考 的大小已知。