如何在 Rust 中匹配向量元素?

8
在 Rust 中,像这样匹配一个值是可行的:
let x = 1;

match x {
    1 => println!("one"),
    2 => println!("two"),
    _ => println!("something else")
}

但是在match中使用向量中的值而不是硬编码的数字是不起作用的:

let x = 1;
let list = vec![1, 2];

match x {
    list[0] => println!("one"),
    list[1] => println!("two"),
    _ => println!("something else")
}

这样做会出现以下错误信息:

error: expected one of `=>`, `@`, `if`, or `|`, found `[`
 --> src/main.rs:6:9
  |
6 |     list[0] => println!("one"),
  |         ^ expected one of `=>`, `@`, `if`, or `|` here

为什么它不能正常工作?

1个回答

17

匹配分支的模式被定义为:

Syntax
Pattern :
     LiteralPattern
   | IdentifierPattern
   | WildcardPattern
   | RangePattern
   | ReferencePattern
   | StructPattern
   | TupleStructPattern
   | TuplePattern
   | GroupedPattern
   | SlicePattern
   | PathPattern
   | MacroInvocation

它要么是恒定的(包括文字)或结构性的,而不是计算出来的。定义为list[0]的值不符合这些定义中的任何一个。

幸运的是,匹配分支也可以包含保护表达式,允许这样做:

let x = 1;
let list = vec![1, 2];

match x {
    _ if x == list[0] => println!("one"),
    _ if x == list[1] => println!("two"),
    _ => println!("something else")
}

使用 if else 会更清晰一些,如果你有更多的情况需要处理,比如一个 map 或者索引,可以尝试使用不同的结构。


去深入了解语法是不错的,但我认为我们可以再高一层次:模式首先是结构性的。除了字面模式的例外,模式从不匹配,而是匹配形状 - Matthieu M.
@MatthieuM,“字面模式的例外”是为什么它会有某种意义,尽管如此,我并不反对更高层次的解释。 - Denys Séguret
我想知道 match() 是否比 match x 更简洁。这将明显表明这里的 match 只是隐藏了一个 if/else 语句块。 - Denys Séguret
然而,真正的问题是 match 有什么用处?一个 if / else 级联也可以工作。不相关的:您不需要在 if 的条件周围加括号。 - Matthieu M.
@MatthieuM 文字常量并不是模式中唯一可能出现的值。常量同样被允许,无数据枚举变体也是如此。 - Sven Marnach
@SvenMarnach:一个没有数据的枚举变量只是枚举模式匹配的一种特殊情况。关于常量的观点很好,随着const fns的出现,这意味着非内置值。 - Matthieu M.

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