如何为枚举实现 PartialEq? [英] How to implement PartialEq for an enum?

查看:48
本文介绍了如何为枚举实现 PartialEq?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下定义:

enum Either<T, U> {
    Left(T),
    Right(U),
}

我如何获得这种类型的 #[derive(PartialEq)] 等价物?我想使用 match 表达式,例如:

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,
        }
    }
}

这会同时消耗 *self*other,即使我只需要它用于 match 表达式,导致错误:

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

推荐答案

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

Normally, you would just use #[derive(PartialEq)], like so:

#[derive(PartialEq)]
enum Either<T, U> {
    Left(T),
    Right(U),
}

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

This will generate the code to implement the trait for you. The Rust Programming Language describes the implementation details.

有时,您想直接实现 trait.这可能是因为默认版本太具体或太笼统.

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,
        }
    }
}

当你创建一个元组时,你会将取消引用的项目移动到元组中,放弃所有权.当你有一个 match *foo 时,你不必放弃所有权.

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.

在现代 Rust 中,您可以用更少的噪音编写相同的东西,因为在模式匹配时会发生更多的隐式引用/取消引用:

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,
        }
    }
}

这篇关于如何为枚举实现 PartialEq?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆