I have the following definition:
enum Either<T, U> { Left(T), Right(U), }
How would I get the equivalent of #[derive(PartialEq)]
for this type? I would like to use a match
expression, like:
impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> { fn eq(&self, other: &Either<T, U>) -> bool { use Either::*; match (*self, *other) { (Left(ref a), Left(ref b)) => a == b, (Right(ref a), Right(ref b)) => a == b, _ => false, } } }
This consumes both *self
and *other
, even though I only need it for the match
expression, causing the error:
error[E0507]: cannot move out of borrowed content --> src/lib.rs:9:16 | 9 | match (*self, *other) { | ^^^^^ cannot move out of borrowed content error[E0507]: cannot move out of borrowed content --> src/lib.rs:9:23 | 9 | match (*self, *other) { | ^^^^^^ cannot move out of borrowed content
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, } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With