如何为枚举实现PartialEq?

Mar*_*iro 11 rust

我有以下定义:

enum Either<T, U> {
    Left(T),
    Right(U),
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到#[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,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这既消耗*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
Run Code Online (Sandbox Code Playgroud)

She*_*ter 20

通常,您只需使用#[derive(PartialEq)],如下所示:

#[derive(PartialEq)]
enum Either<T, U> {
    Left(T),
    Right(U),
}
Run Code Online (Sandbox Code Playgroud)

这将生成为您实现特征的代码.Rust编程语言描述了实现细节.


有时,您希望直接实现特征.这可能是因为默认版本太具体或太通用.

您的情况中的错误是您需要模式匹配引用而不是尝试取消引用它们:

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,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当你创建一个元组时,你会将解除引用的项目移动到元组中,放弃所有权.如果你有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,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它产生生锈代码,你只是看不到因为它在编译过程中发生,而不是在源代码中. (4认同)