【问题标题】:Wrong trait chosen based on type parameter基于类型参数选择的错误特征
【发布时间】:2018-11-02 20:21:59
【问题描述】:

我有一个二元特征Resolve

pub trait Resolve<RHS = Self> {
    type Output;
    fn resolve(self, rhs: RHS) -> Self::Output;
}

我实现了一些微不足道的特征,其中两个参数都是通过引用获取的(self&amp;'a Foorhs&amp;'b Foo):

struct Foo;

impl <'a, 'b> Resolve<&'b Foo> for &'a Foo {
    type Output = Foo;
    fn resolve(self, rhs: &'b Foo) -> Self::Output {
        unimplemented!()
    }
}

如果我现在写

fn main() {
    let a: &Foo = &Foo;
    let b = Foo;
    a.resolve(&b);
}

它会编译得很好,但如果我尝试在我的结构 Signal 上实现它,它将无法工作。

pub struct Signal<'a, T> {
    ps: Vec<&'a T>,
}

impl<'a, T: Resolve<&'a T, Output = T> + 'a> Signal<'a, T> {
    pub fn foo(&mut self) {
        let a: &T = &self.ps[0];
        let b = &self.ps[1];
        a.resolve(b);
    }
}
error[E0507]: cannot move out of borrowed content
  --> src/main.rs:25:9
   |
25 |         a.resolve(b);
   |         ^ cannot move out of borrowed content

如何让这个示例正常工作? (playground)

【问题讨论】:

    标签: rust


    【解决方案1】:

    foo 上的 trait 仅表示 T 实现了 Resolve,但您尝试在 &amp;T 类型的值上调用 .resolve()

    要说,referencesT 必须实现 Resolve,你需要一个 higher-ranked trait bound

    impl<'a, T> Signal<'a, T>
    where
        for<'b> &'b T: Resolve<&'a T, Output = T>,
    {
        pub fn foo(&mut self) { ... }
    }
    

    【讨论】:

      【解决方案2】:

      考虑到这一点,我想出了一个不依赖 HRTB 的更简单的解决方案。

      impl<'a, T> Signal<'a, T>
      where
          &'a T: Resolve<&'a T, Output = T> + 'a,
      {
          pub fn foo(&mut self) {
              let a: &T = &self.ps[0];
              let b = &self.ps[1];
              a.resolve(b);
          }
      }
      

      这与 &amp;T 实现 Resolve 的作用相同,即描述,但不需要 HRTB。
      为此,您必须使用 where clause,但除此之外,这是一个不错且简单的解决方案。

      【讨论】:

      • 你是对的,在这种情况下它确实有效,因为&amp;'a TCopy(注意&amp;self.ps[0] 中的&amp; 没有任何作用,可以删除)。在更复杂的场景中,您必须重新借用 self 的生命周期,您将需要 HRTB。
      猜你喜欢
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多