Булево выражение для проверки соответствия выражения шаблону в Rust - PullRequest
1 голос
/ 09 апреля 2020

У меня есть Vec значений и я хочу filter тех, которые соответствуют определенному шаблону.
Что такое идиоматический c способ просто проверить , если выражение соответствует шаблону , не обязательно что-то делать с соответствием?

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
  }
})

Но в обоих примерах код все еще выглядит громоздким, потому что мне нужно вручную предоставить константы true и false. Я чувствую, что должен быть более элегантный способ сделать это, что-то похожее на следующее:

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

Ответы [ 2 ]

3 голосов
/ 09 апреля 2020

Для этого есть макрос с именем matches!! 1002 *

vector.filter(|item| matches!(item, Some(Kind::B(_))))
0 голосов
/ 09 апреля 2020

Вы можете использовать функцию 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);
}

Строка Commend аналогична строке с .filter(|item| item.is_some()), но короче. Я оставил более длинную версию для лучшего понимания.

Rust Playground

...