我的代码看起来像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`
我认为我在概念上误解了一些东西。
你可以通过查看&&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)
。