我有以下定义:
enum Either<T, U> {
Left(T),
Right(U),
}
我怎么能得到这种类型的#[derive(PartialEq)]
?我想使用match
表达式,如:
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,
}
}
}
这会消耗*self
和*other
,即使我只需要它用于match
表达式,导致错误:
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
通常,您只需使用#[derive(PartialEq)]
,如下所示:
#[derive(PartialEq)]
enum Either<T, U> {
Left(T),
Right(U),
}
这将生成为您实现特征的代码。 The Rust Programming Language describes the implementation details。
有时,您希望直接实现特征。这可能是因为默认版本太具体或太通用。
您的情况中的错误是您需要模式匹配引用而不是尝试取消引用它们:
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,
}
}
}
当你创建一个元组时,你会将解除引用的项目移动到元组中,放弃所有权。当你有match *foo
时,你不必放弃所有权。
在现代Rust中,您可以使用较少的噪声编写相同的内容,因为在模式匹配时会发生更多隐式引用/解除引用:
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,
}
}
}