Does this error message mean I can use pattern matching in for loops?
Yes, you can use patterns in many places, but not all of them allow you to conditionally branch when there are multiple possible patterns.
A for
loop is one place where you cannot add conditions. That's what the error is telling you with "refutable pattern": there's a pattern that will not be handled. Instead, you mostly use the pattern to perform destructuring of the loop variable:
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);
}
}
Conditional:
match
if let
while let
Unconditional:
for
let
- function parameters
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.