为什么Rust期望双借(`&&'mut T`)

问题描述 投票:0回答:1

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

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

types rust borrow-checker borrowing
1个回答
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)

© www.soinside.com 2019 - 2024. All rights reserved.