此错误消息是否意味着我可以在for循环中使用模式匹配?

Ear*_*ine 14 rust

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

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

错误消息是

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
Run Code Online (Sandbox Code Playgroud)

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

tre*_*tcl 14

您可以使用模式作为for循环中的绑定,但不能使用可替换的模式.这里描述了refutable和irrefutable模式之间的区别,但它的要点是,如果模式可能失败,则不能在let语句或for循环中使用它.如果模式不能失败,则不能(当前)在if let或中使用它while let.(这可能会在将来的版本中更改,以发出警告而不是失败.)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

for tuple in &numbers {
    let (name, number) = tuple;
    println!("{}: {}", name, number);
}
Run Code Online (Sandbox Code Playgroud)

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


She*_*ter 7

是的,您可以在许多地方使用模式,但并非所有模式都允许您在有多种可能的模式时有条件地分支.

一个for循环是一个地方,你可以不加条件.这就是错误告诉你的"可反复模式":有一种模式无法处理.相反,您主要使用该模式来执行循环变量的解构:

struct Thing {
    foo: u8,
}

fn main() {
    let things = vec![Thing { foo: 1 }, Thing { foo: 2 }, Thing { foo: 3 }];
    for Thing { foo } in things {
        println!("{}", foo);
    }
}
Run Code Online (Sandbox Code Playgroud)

条件:

  • match
  • if let
  • while let

无条件的:

  • for
  • let
  • 功能参数