我的代码看起来像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`
我认为我在概念上误会了一些东西。
答案 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)
。