为什么Rust会期望两次借入('&&'a mut T`)

时间:2019-03-28 21:10:27

标签: types rust borrow-checker borrowing

我的代码看起来像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`

我认为我在概念上误会了一些东西。

1 个答案:

答案 0 :(得分:4)

通过查看&&mut T特性中eq()方法的定义,您可以了解Rust为何期望PartialEq

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

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

在这种情况下,Self是什么?你的特质是这样的:

&'a mut T: PartialEq

因此,编译器可以使用的唯一PartialEq实现是类型&'a mut T的实现,因此Self就是这样。反之,&Self必须为&&'a mut T,这正是编译器所期望的。

您可能希望将特征绑定到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(&a, &b)