Patterns assign values to variable names

When we use a variable name in a pattern, it matches any value and the matched value is stored in the variable. That means that if we were to try this:

let x = 5;
let source6 = DemoStruct {id: 7, name: String::from("oops"), probability: 0.26};
if let DemoStruct { id: x, name: _, probability: _ } = source6 {
println!("The pattern matched, x is {}", x);
}

We do not get a pattern that compares the source6.id value to the value of x (five in this case), we don't get what we expect.

Instead, we get an error saying that the pattern is irrefutable:

Irrefutable means the pattern will never fail to match, which is a problem in an if let expression.

If we try a similar pattern that it is refutable, but still uses the x variable, the program compiles, but the pattern matches when we didn't want it to:

let x = 5;
let source6 = DemoStruct {id: 7, name: String::from("oops"), probability: 0.26};
if let DemoStruct { id: 7, name: x, probability: _ } = source6 {
println!("The pattern matched, x is {}", x);
}

Both of these situations arise because of a rule we already talked about: variable names used in patterns match any value, and store the matched value into a new variable with the given name. If we think about it, that implies that if there's already a variable with that name, its current value doesn't matter.

That doesn't mean we're entirely out of luck, though. We can use an extension of the match syntax to involve existing variables in the decision:

let x = 5;
let source7 = DemoStruct {id: 7, name: String::from("oops"), probability: 0.26};
match source7 {
DemoStruct { id: y, name: _, probability: _ } if y == x => {
println!("The pattern with match guard matched, y is {}", y);
}
_ => {
println!("The pattern with match guard did not match")
}
}

What we're doing here is applying a match guard to the pattern. We do that by putting the if keyword after the pattern, but before the =>, and following it up with a Boolean expression. This lets us add non-pattern matching criteria to a match branch. In this case, we're saying that if the pattern matches and the ID (stored in y) matches the value stored in x, we should run that block of code.

There has been talk of creating a similar feature for if let, but mostly people just use nested if expressions or match.

When we use a match guard, we need to be especially careful that our pattern doesn't shadow any variable names we want to use in the guard. That's why, in this example, we matched the id of DemoStruct to a variable named y instead of x. We needed to keep x around so our match guard could use it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.158.36