2014-08-29 55 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); 
    } 
} 

参见: