fn run() {
for &mut input in &mut [16, 23, 42, 43] {
match input {
23 => println!("Input is equal to a"),
16 => println!("Input is equal to b"),
43 => println!("Input is equal to c"),
_ => println!("Input does not equal any value"),
}
}
}
Despite the fact that variables does not change, the compiler is silent, like a fish on ice. Why? Thanks.
You're not creating two references here, instead you're using a pattern to automatically dereference.
let &mut x = &mut 3;
This results in x = 3.
In a sense, this operation on the "place" (x in this case) undoes what it'd do to a "value" (3).
In your example, you take a reference to the array, &mut [16, 23, 42, 43], which yields values of type &mut i32, however you then assign this to a "place" which undoes this reference (through a pattern matching).
Take a look at this playground and try changing it to not use &mut in &mut input. It'll print different types.
Note that terminology-wise, this is not a “place vs. value” discinction. Place expressions and value expressions are both expressions. While, as an expression, indeed x would be a place expression and 3 a value expression, the reason that the meaning of &mut x and &mut 3 is different here is instead based on where the thing appears (left-hand side of the = in a let vs. right-hand side). The discinction is between expressions (&mut …) and patterns (&mut …)!
It's correct to say that the &mut …pattern does, in a sense, undo what the &mut …expression does. But it acts on the thing being matched against, not on the subpattern. (Matching against) the &mut x pattern is an operation that acts on the &mut 3 expression, dereferencing it back to the value 3[1] and subsequently "passing" this value 3 to on to the subpattern x. This next step of matching 3 against x just assigns 3 to x[2].
or, more precisely, to the place containing the value 3↩︎
or, more precisely, matching the place containing the value 3 to the pattern x copies the value out of that place and assigns it to x↩︎