枚举运算符如何重载?

时间:2018-10-30 19:52:49

标签: rust

我有一个枚举:

enum Numbers {
    A = 1,
}

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

let a = Numbers::A < 4

我想我在某处读到了可以使用某种宏的方法?也许有一个箱子可以让我这样做?到目前为止,我唯一获得成功的是as u32,但是每次都必须写出来很繁琐。

1 个答案:

答案 0 :(得分: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`

因此,实现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;
}

Sven Marnach points out

  

可能需要指出的是,此实现只允许与左侧的Numbers和右侧的i32进行比较。像4 > Numbers::ANumbers.A < Numbers.B之类的比较将需要单独的实现。另外,由于要处理整数,因此您还想实现OrdEq,因此对于所有操作数组合,最终都有十二种特征实现。

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

  • 如果您想将NumbersNumbers进行比较,则可以## derive(PartialOrd)]。
  • 如果需要Eq,则可以派生它。
  • 您可以编写宏以减少某些冗余。

另请参阅: