如何用值检查枚举

How to check enum with values

如何检查枚举向量是否具有某个成员的值?

#[derive(PartialEq,Clone,Copy)]
enum TestResult {
    Pass,
    Fail {point: u8},
}
impl TestResult {
    fn is_fail(&self) -> bool {
        match *self {
            TestResult::Fail{point:_} => true,
            _ => false,
        }
    }
}
fn main() {
    let v1 = vec![TestResult::Pass,
                  TestResult::Pass,
                  TestResult::Fail{point:50}];
    if v1.contains(&TestResult::Pass) {
        println!("result contains Pass");
    }
    if v1.iter().any(|&r| r.is_fail()) {
        println!("result contains Fail");
    }
}

这是有效的,但是有没有办法用 Vec::contains() 来做到这一点? 我想检查 TestResult::Fail 是否以与 TestResult::Pass 相同的方式在向量中(没有模式匹配。简单..)

确实没有简单的方法来做到这一点,但是我们可以制作一个简单的宏来在 if 语句中执行一些模式匹配。

/// Performs pattern matching contains on an IntoIter type
macro_rules! matches_any {
    ($iterable:expr, $($tokens:tt)+) => {{
        let iter = ::std::iter::IntoIterator::into_iter($iterable);
        iter.any(|x| matches!(x, $($tokens)+))
    }};
}

这里的技巧是,如果我们只想知道某些东西是否匹配给定的模式,我们可以使用 matches! 宏而不是完整的 match 语句。

// Without matches!
match self {
    TestResult::Fail {..} => true,
    _ => false,
}

// With matches!
matches!(self, TestResult::Fail {..})

现在我们可以改用这个宏了:

let v1 = vec![TestResult::Pass,
              TestResult::Pass,
              TestResult::Fail { point: 50 }];

if matches_any!(&v1, TestResult::Pass) {
    println!("result contains Pass");
}

if matches_any!(&v1, TestResult::Fail {..}) {
    println!("result contains Fail");
}