0

为什么这里需要关联类型,即使它从未使用过?

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
4

1 回答 1

1

您正在制作一个 trait 对象,并且需要指定所有关联类型的 trait 对象。您的情况非常简单,并且 trait 的方法不使用关联类型,但对象安全规则是为更一般的情况设计的。

如果您只是使用由 绑定的类型参数,Tr则无需指定关联的类型:

fn foo<T: Tr>(t: T) -> () {
    t.go()
}

那是因为可以为T您调用的每个类型推断出关联的类型foo

如果允许特征对象具有未指定的关联类型,则函数内的代码将无法推断它。在这种情况下,您可能会争辩说,这应该只是限制允许函数执行的操作,但对象安全规则是针对 trait 对象类型的定义给出的,而不管它是如何实际使用的。这使得考虑起来更简单,因为在某些情况下可以使用 trait 对象,而在其他情况下则不能。


顺便说一句,即使您在函数签名中指定了对象的关联类型,您也必须通过引用或装箱来传递对象,例如:

fn foo(t: &dyn Tr<Ty = SomeType>) -> () {
    t.go()
}

这是因为 trait 对象在编译时没有已知的大小。相反,您需要将它们放在一个具有已知大小的参考后面

于 2019-12-07T01:03:54.713 回答