如何在枚举上进行运算符重载?

2 rust

我有一个枚举:

enum Numbers {
    A = 1,
}
Run Code Online (Sandbox Code Playgroud)

如何重载运算符,以便我可以将Numbers枚举与另一个标准数字进行比较而无需执行此操作as u32?如果我想这样做:

let a = Numbers::A < 4
Run Code Online (Sandbox Code Playgroud)

我想我在某个地方读到了可以用某种宏做的事情?也许有一个箱子可以让我这样做?到目前为止,我唯一能取得成功的是,as u32但每次都必须把它写出来是相当繁琐的.

She*_*ter 5

您可以使用与为结构重载运算符完全相同的方式执行它:实现适当的std::ops特征.

但是,你真的不想超载的含义<,你仍然希望进行比较.

如果您运行您键入的代码,编译器会告诉您该怎么做:

error[E0369]: binary operation `<` cannot be applied to type `Numbers`
 --> src/main.rs:6:13
  |
6 |     let a = Numbers::A < 4;
  |             ^^^^^^^^^^^^^^
  |
  = note: an implementation of `std::cmp::PartialOrd` might be missing for `Numbers`
Run Code Online (Sandbox Code Playgroud)

所以,实施PartialOrd:

#[derive(Copy, Clone)]
enum Numbers {
    A = 1,
}

use std::cmp::Ordering;

impl PartialEq<i32> for Numbers {
    fn eq(&self, other: &i32) -> bool {
        (*self as i32).eq(other)
    }
}

impl PartialOrd<i32> for Numbers {
    fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
        (*self as i32).partial_cmp(other)
    }
}

fn main() {
    let a = Numbers::A < 4;
}
Run Code Online (Sandbox Code Playgroud)

正如Sven Marnach所指出的那样:

值得指出的是,此实现仅允许Numbers在左侧和i32右侧进行比较.比较喜欢4 > Numbers::ANumbers.A < Numbers.B需要单独的实现.此外,因为你面对的整数,你也会想实现OrdEq,所以对于操作数的所有组合你最终会得到十二个特质的实现.

当然,这取决于您的具体情况:

  • 如果你想比较NumbersNumbers,你也许能#[导出(PartialOrd).
  • 如果你愿意Eq,你可以推导它.
  • 你可以编写宏来减少一些冗余.

也可以看看:

  • 值得指出的是,这种实现只允许与左侧的"数字"和右侧的"i32"进行比较.像`4> Numbers :: A`和`Numbers.A <Numbers.B`这样的比较需要单独的实现.另外,由于你正在处理整数,你还需要实现`Ord`和`Eq`,因此对于所有操作数组合,你最终会得到12个特征实现. (2认同)