Normally, you would just use #[derive(PartialEq)]
, like so:
#[derive(PartialEq)]
enum Either<T, U> {
Left(T),
Right(U),
}
This will generate the code to implement the trait for you. The Rust Programming Language describes the implementation details.
Sometimes, you want to implement the trait directly. This may be because the default version is either too specific or too generic.
The error in your case is that you you need to pattern match the references instead of trying to dereference them:
impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> {
fn eq(&self, other: &Self) -> bool {
use Either::*;
match (self, other) {
(&Left(ref a), &Left(ref b)) => a == b,
(&Right(ref a), &Right(ref b)) => a == b,
_ => false,
}
}
}
When you create a tuple, you would be moving the dereferenced item into the tuple, giving up ownership. When you have a match *foo
, you don't have to give up the ownership.
In modern Rust, you can write the same thing with less noise because more implicit referencing / dereferencing occurs when pattern matching:
impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> {
fn eq(&self, other: &Self) -> bool {
use Either::*;
match (self, other) {
(Left(a), Left(b)) => a == b,
(Right(a), Right(b)) => a == b,
_ => false,
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…