【问题标题】:"associated type ... must be specified", but isn't used“关联类型...必须指定”,但未使用
【发布时间】:2019-12-06 23:51:34
【问题描述】:
为什么这里需要关联类型,即使它从未使用过?
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
【问题讨论】:
标签:
rust
associated-types
dynamic-dispatch
trait-objects
【解决方案1】:
您正在制作一个 trait 对象,并且需要指定所有关联类型的 trait 对象。您的情况非常简单,并且 trait 的方法不使用关联类型,但 object safety rules 是为更一般的情况设计的。
如果您只是使用由Tr 绑定的类型参数,则无需指定关联类型:
fn foo<T: Tr>(t: T) -> () {
t.go()
}
这是因为可以为您调用 foo 的每个 T 推断出关联类型。
如果允许特征对象具有未指定的关联类型,则函数内的代码将无法推断它。在这种情况下,您可以争辩说,这应该只是限制允许函数执行的操作,但对象安全规则是针对 trait 对象类型的定义给出的,而不管它是如何实际使用的.这使得考虑起来更简单,因为在某些情况下可以使用 trait 对象,而在其他情况下则不能。
顺便说一句,即使您在函数签名中指定了对象的关联类型,您也必须通过引用或装箱来传递对象,例如:
fn foo(t: &dyn Tr<Ty = SomeType>) -> () {
t.go()
}
这是因为 trait 对象在编译时没有已知的大小。相反,您需要将它们放在参考后面,该参考确实具有已知大小。