【问题标题】:Why does Rust expect double borrow (`&&'a mut T`)为什么 Rust 期望双借(`&&'a mut T`)
【发布时间】:2019-03-28 21:10:27
【问题描述】:

我的代码看起来像this:

pub enum Cache<'a, T> {
    Pending(&'a dyn FnOnce() -> T),
    Cached(T),
}

impl<'a, T> Cache<'a, T> {
    pub fn get(&self) -> &mut T {
        // This caches and borrows the T
    }
}

impl<'a, T> PartialEq for Cache<'a, T>
    where &'a mut T: PartialEq {

    fn eq(&self, other: &Self) -> bool {
        self.get().eq(other.get())
    }
}

但实现 Eq 失败:

error[E0308]: mismatched types
--> src/lib.rs:20:23
|
20 |         self.get().eq(other.get())
|                       ^^^^^^^^^^^ expected mutable reference, found type parameter
|
= note: expected type `&&'a mut T`
               found type `&mut T`

我想我在概念上误解了一些东西。

【问题讨论】:

  • 您是要比较T 对象本身,还是比较.get() 返回的引用?
  • @Frxstrem 在功能上,我希望 T 对象相同。
  • &amp;'a dyn FnOnce() -&gt; T 看起来像是一个有问题的类型,因为您永远无法调用该函数。 (您需要拥有FnOnce 才能调用它。)

标签: types rust borrow-checker borrowing


【解决方案1】:

您可以通过查看 PartialEq 特征中 eq() 方法的定义来理解为什么 Rust 期待 &amp;&amp;mut T

fn eq(&self, other: &Rhs) -> bool;

该方法的参数类型为&amp;Self&amp;Rhs;由于Rhs 默认为Self,并且您没有在特征绑定中指定任何其他内容,因此两个参数都应为&amp;Self 类型。

现在Self 在这种情况下是什么?你的 trait bound 是这样的:

&'a mut T: PartialEq

所以编译器可以使用的唯一PartialEq 实现是&amp;'a mut T 类型的实现,所以这就是Self&amp;Self 又必须是 &amp;&amp;'a mut T,这正是编译器所期望的。

您可能希望将 trait 绑定到 T

impl<'a, T> PartialEq for Cache<'a, T>
where
    T: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.get() == other.get()
    }
}

另请注意,您可以简单地使用== 而不是显式调用eq()。它使正确的类型更容易一些,因为编译器将隐式引用参数 - a == b 扩展为 PartialEq::eq(&amp;a, &amp;b)

【讨论】:

  • 我根据我在尝试self.get().eq(other.get()) 时得到的编译器提示添加了&amp;'a mut。但现在我发现我应该改用&amp;other(或者更简单,==)。
猜你喜欢
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多