【问题标题】:"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 对象在编译时没有已知的大小。相反,您需要将它们放在参考后面,该参考确实具有已知大小。

    【讨论】:

      猜你喜欢
      • 2018-11-18
      • 2018-06-30
      • 2016-06-29
      • 2017-12-12
      • 2019-12-23
      • 2016-07-29
      • 2015-09-13
      • 2018-12-18
      • 2017-08-31
      相关资源
      最近更新 更多