首页 > 解决方案 > 此错误消息是否意味着我可以在 for 循环中使用模式匹配?

问题描述

我不希望以下代码起作用,但作为语法探索的一部分,我在操场上尝试过:

fn main() {
    struct EOF {};
    let lines = vec![Ok("line 1"), Ok("line 2"), Err(EOF {})];
    for Ok(line) in lines {
        println!("{}", line);
    }
}

错误信息是

error[E0005]: refutable pattern in `for` loop binding: `Err(_)` not covered
 --> src/main.rs:4:9
  |
4 |     for Ok(line) in lines {
  |         ^^^^^^^^ pattern `Err(_)` not covered

根据上面的消息,看起来我只需要为Err案例添加一个匹配臂。但是这样做的正确语法是什么?

标签: rust

解决方案


您可以将模式用作for循环中的绑定,但不能使用可反驳的模式。这里描述了可反驳和不可反驳模式之间的区别,但它的要点是,如果一个模式可能失败,你不能在let语句、for循环、函数或闭包的参数或其他地方使用它语法特别需要一个无可辩驳的模式。

在循环中使用无可辩驳的模式的示例for可能是这样的:

let mut numbers = HashMap::new();
numbers.insert("one", 1);
numbers.insert("two", 2);
numbers.insert("three", 3);

for (name, number) in &numbers {
    println!("{}: {}", name, number);
}

(name, number)是一个无可辩驳的模式,因为它类型检查的任何地方都会匹配。它在这里键入检查,因为被迭代的项目(由IntoIteratorfor的实现定义&HashMap)是元组。你也可以把上面写成

for tuple in &numbers {
    let (name, number) = tuple;
    println!("{}: {}", name, number);
}

因为let是另一个只允许无可辩驳的模式的地方。


推荐阅读