Rust中用于检查表达式是否与模式匹配的布尔表达式

8
我有一个包含值的`Vec`,想要筛选出符合特定模式的值。
如果只是想检查一个表达式是否匹配某个模式,并不一定需要对匹配结果进行操作,有什么惯用方法吗?
enum Kind {
    A,
    B(char),
}

let vector: Vec<Option<Kind>> = ...;
vector.filter(|item| /* check if item matches pattern Some(Kind::B(_)) */)

我知道我可以使用“match”关键字:
vector.filter(|item| match item {
  Some(Kind::B(_)) => true,
  _ => false,
})

或者是if let关键字:

vector.filter(|item| {
  if let Some(Kind::B(_)) = item {
    true
  } else {
    false
  }
})

但是在这两个示例中,代码看起来仍然很臃肿,因为我需要手动提供truefalse常量。我觉得应该有一种更优雅的方式来做到这一点,类似于下面这样:

vector.filter(|item| matches(item, Some(Kind::B(_))))
2个回答

12

有一个名为matches!的宏可以做到这一点!

vector.filter(|item| matches!(item, Some(Kind::B(_))))

这是正确答案,因为你无法将“模式”存储在常规变量中。因此,需要使用宏变量来存储模式。 - Optimistic Peach
值得注意的是,matches!仅在 Rust 的最新版本(1.42.0)不到一个月前才被稳定下来,因此根据 Rust 上次更新的时间,可能需要更新才能使用它。 - Frxstrem

-1
你可以使用 Option::is_some 函数。这是一个例子:
#[derive(Debug)]
enum Kind {
    A,
    B(char),
}

fn main() {
    let vec_of = vec![Some(Kind::A), Some(Kind::B('x')), None, None];

    // let col: Vec<Option<Kind>> = vec_of.into_iter().filter(Option::is_some).collect();
    let col: Vec<Option<Kind>> = vec_of.into_iter().filter(|item| item.is_some()).collect();

    println!("{:?}", col);
}

命令行与 .filter(|item| item.is_some()) 相同,但更短。我也留下了更长的版本以便更好地理解。

Rust Playground


2
这仅适用于 Option,而不适用于其中的内容。例如,我无法检查问题中的模式,即 Some(Kind::B(_)) - Marcel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接