Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare enum without pattern matching

I want to apply filter on an iterator and I came up with this one and it works, but it's super verbose:

.filter(|ref my_struct| match my_struct.my_enum { Unknown => false, _ => true }) 

I would rather write something like this:

.filter(|ref my_struct| my_struct.my_enum != Unknown) 

This gives me a compile error

binary operation `!=` cannot be applied to type `MyEnum` 

Is there an alternative to the verbose pattern matching? I looked for a macro but couldn't find a suitable one.

like image 570
Christoph Avatar asked Aug 29 '14 21:08

Christoph


People also ask

Can you use == on enum Java?

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

Can we compare enum with INT?

Cast Int To Enum may be of some help. Go with the 2nd option. The 1st one can cause an exception if the integer is out of the defined range in your Enumeration. In current example I compare to 'magic number' but in real application I am getting data from integer field from DB.

Can == be used on enum?

equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.


2 Answers

Use matches!, e.g.:

matches!(my_struct.my_enum, Unknown) 

Alternatively, you can use PartialEq trait, for example, by #[derive]:

#[derive(PartialEq)] enum MyEnum { ... } 

Then your "ideal" variant will work as is. However, this requires that MyEnum's contents also implement PartialEq, which is not always possible/wanted.

like image 99
Vladimir Matveev Avatar answered Sep 28 '22 10:09

Vladimir Matveev


I'd use pattern matching, but I'd move it to a method on the enum so that the filter closure is tidier:

#[derive(Debug)] enum Thing {     One(i32),     Two(String),     Unknown, }  impl Thing {     fn is_unknown(&self) -> bool {         match *self {             Thing::Unknown => true,             _ => false,         }     } }  fn main() {     let things = [Thing::One(42), Thing::Two("hello".into()), Thing::Unknown];     for t in things.iter().filter(|s| !s.is_unknown()) {         println!("{:?}", t);     } } 

You can combine this with the matches macro as well:

fn is_unknown(&self) -> bool {     matches!(self, Thing::Unknown) } 

See also:

  • Compare enums only by variant, not value
like image 25
Shepmaster Avatar answered Sep 28 '22 10:09

Shepmaster