匹配在其字段之一中采用向量的枚举

Match an enum that takes a vector in one of its fields

我正在尝试将事件与 pulldown_cmark 标题的开头相匹配。 假设我有这个:

enum MyEvent<'a> {
    Start(MyTag<'a>),
    End(MyTag<'a>),
}

enum MyTag<'a> {
    Heading(SomeHeadingLevelEnum, Option<&'a str>, Vec<&'a str>,
    Paragraph,
}

fn main() {
    // Simplified the enums for the sake of the example
    let event = Start(Heading(Level::H1, None, vec![]));
}

如何将事件与类型匹配?尝试过:

fn main() {
    // ...
    match event {
        Start(Heading(H1, None, [])) => println!("a heading!"),
        _ => println!("yeah not a type I know for sure"),
    }
}

但得到了:

Start(Heading(H1, None, [])) => println!("a H1!")                                        
                        ^^ pattern cannot match with input type `Vec<&str>`

我尝试了其他方法,如使用 vec![]&[&str]Vec::new(""),但也遇到了其他错误。

你不能在这样的 match 表达式中有一个表达式,它在那里取一个变量,如果存在的话,它会填充一个成功的匹配项。如果你希望它只在 Vec 为空时成功,那么你可以使用 match guard 来检查它:

match event {
    Start(Heading(H1, None, v)) if v.is_empty() => println!("a heading!"),
    _ => println!("yeah not a type I know for sure"),
}

旁注:与其像那样在 enums 中使用 &str,不如使用 String,这样就不必传播那些讨厌的生命周期注释无处不在。

您无法匹配特定长度的 Vec。作为一种模式,[] 匹配长度为零的数组,这与 Vec.

不同

相反,您可以匹配变量并为其添加空值保护:

match event {
    Start(Heading(H1, None, lines)) if lines.is_empty() => println!("a heading!"),
    _ => println!("yeah not a type I know for sure"),
}

遗憾的是它不是那样工作的,你必须匹配它然后在匹配分支中使用守卫:

match &event {
    MyEvent::Start(MyTag::Heading(Heading::H1, None, v)) if v.is_empty() => println!("a heading!"),
    _ => println!("yeah not a type I know for sure"),
}

Playground