如何在没有模式匹配的情况下比较枚举

Posted

技术标签:

【中文标题】如何在没有模式匹配的情况下比较枚举【英文标题】:How to compare enum without pattern matching 【发布时间】:2014-10-23 23:10:23 【问题描述】:

我想在迭代器上应用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`

是否有替代详细模式匹配的方法?我找了一个宏,但找不到合适的。

【问题讨论】:

【参考方案1】:

使用matches!,例如:

matches!(my_struct.my_enum, Unknown)

或者,您可以使用PartialEq trait,例如#[derive]

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

然后您的“理想”变体将按原样工作。但是,这要求MyEnum 的内容也实现PartialEq,这并不总是可能/想要的。

【讨论】:

【参考方案2】:

我会使用模式匹配,但我会将它移动到枚举上的一个方法中,以便过滤器闭包更整洁:

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

您也可以将其与matches macro 结合使用:

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

另见:

Compare enums only by variant, not value

【讨论】:

简洁优雅。不能直接比较似乎总是违反直觉的(对于像我这样的 Rust 新手),但是“在方法中使用模式匹配”方法确实在鼓励更多可测试、模块化方面大有帮助代码..【参考方案3】:

您可以将if let Some(x) = option then 成语与相同的if let 构造一起使用,但无需解构:

if let Unknown = my_struct.my_enum  false  else  true 

【讨论】:

我很惊讶你不能只当 my_struct.my_enum == enum_value 你可以。与#[derive(Eq)] 看来你需要#[derive(Eq, PartialEq)]

以上是关于如何在没有模式匹配的情况下比较枚举的主要内容,如果未能解决你的问题,请参考以下文章

字符串模式匹配算法 BM

如何对包装String的枚举变体进行模式匹配? [重复]

如何阻止创建名称与特定模式匹配的 MySQL 数据库

Scala模式匹配Java枚举值

如何在不知道其结构的情况下创建匹配枚举变体的宏?

Perl中的多个模式的字符串匹配