"associated type ... must be specified",但未被使用

"associated type ... must be specified", but isn't used

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

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

您正在制作特征对象,特征对象要求指定所有关联类型。你的情况非常简单,特征的方法不使用关联类型,但 object safety rules 是为更一般的情况设计的。

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

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

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

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


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

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

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