2014-08-29 14 views
14

Chcę zastosować filter na iteracyjnej i wpadłem na ten jeden i to działa, ale jest to bardzo gadatliwy:Jak porównać wyliczenia bez dopasowywania wzorców

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

wolałbym napisać coś takiego:

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

To daje mi błąd kompilacji

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

Czy istnieje alternatywa dla vE Dopasowanie wzorca rbose? Szukałem makra, ale nie mogłem znaleźć odpowiedniego.

Odpowiedz

26

Po pierwsze, można użyć PartialEq cechę, na przykład, przez #[derive]:

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

Wtedy twój "idealny" wariant będzie działać tak jak jest. Jednak wymaga to, aby zawartość MyEnum implementowała także PartialEq, co nie zawsze jest możliwe/pożądane.

Po drugie, można wdrożyć makro samodzielnie, coś takiego (choć to makro nie obsługuje wszystkie rodzaje wzorów, na przykład, alternatywy):

macro_rules! matches(
    ($e:expr, $p:pat) => (
     match $e { 
      $p => true, 
      _ => false 
     } 
    ) 
) 

Wtedy go używać tak:

.filter(|ref my_struct| !matches!(my_struct.my_enum, Unknown)) 

Istnieje an RFC, aby dodać takie makro do biblioteki standardowej, ale nadal jest ono przedmiotem dyskusji.

+1

Doskonała odpowiedź jak zwykle! "PartialEq" działa jak czar w moim przypadku. – Christoph

0

użyję pasujące do wzorca, ale chciałbym przenieść go do metody na wyliczenia tak, że zamknięcie filtr jest porządniej:

#[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 = vec![Thing::One(42), Thing::Two("hello".into()), Thing::Unknown]; 
    for t in things.iter().filter(|s| !s.is_unknown()) { 
     println!("{:?}", t); 
    } 
} 

Patrz także:

Powiązane problemy