Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does this error message mean I can use pattern matching in for loops?

Tags:

rust

I do not expect the following code to work, but as part of grammar exploration, I tried in playground:

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

The error message is

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

According to the message above it looks like I only need to add a match arm for the Err case. But what is the right grammar to do so?

like image 485
Earth Engine Avatar asked Jun 01 '18 13:06

Earth Engine


People also ask

Can you explain any three shift pattern matching techniques in Swift?

Pattern Matching TypesType-casting patterns allow you to cast or match types. Wildcard patterns match and ignore any kind and type of value. Optional patterns are used to match optional values. Enumeration case patterns match cases of existing enumeration types.

What is pattern matching in C#?

Pattern matching is a technique where you test an expression to determine if it has certain characteristics. C# pattern matching provides more concise syntax for testing expressions and taking action when an expression matches.


1 Answers

You can use patterns as the binding in a for loop, but not refutable patterns. The difference between refutable and irrefutable patterns is described here, but the gist of it is, if a pattern could fail, you can't use it in a let statement, a for loop, the parameter of a function or closure, or other places where the syntax specifically requires an irrefutable pattern.

An example of an irrefutable pattern being used in a for loop might be something like this:

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) is an irrefutable pattern, because any place where it type checks, it will match. It type checks here because the items being iterated over (defined by the implementation of IntoIterator for &HashMap) are tuples. You could also write the above as

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

because let is another place where only irrefutable patterns are allowed.

like image 96
trent Avatar answered Sep 28 '22 17:09

trent