2014-08-29 71 views
14

我想在一個迭代應用filter,我想出了這個和它的作品,但它的超詳細:如何比較枚舉無圖案匹配

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

我寧願寫的是這樣的:

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

這給了我一個編譯錯誤

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

是否有可以替代已經rbose模式匹配?我尋找一個宏,但找不到合適的。

回答

26

首先,你可以使用PartialEq性狀,例如,通過#[derive]

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

那麼你的 「理想」 的變體將作爲是。但是,這需要MyEnum的內容也實現PartialEq,這並不總是可能/想要的。

其次,你可以實現自己的宏,像這樣的東西(雖然該宏不支持各種圖案,例如,替代):

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

然後你會使用這樣的:

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

an RFC將這樣的宏添加到標準庫中,但它仍在討論中。

+1

像往常一樣很好的回答!對我而言,'PartialEq'就像一個迷人的東西。 – Christoph 2014-08-29 22:43:52

0

我會使用模式匹配,但使得濾波器關閉是整潔我將它移動到方法上枚舉:

#[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); 
    } 
} 

參見: