Let's say that I have an Option<String>
and want to pattern match to get a mutable reference to the String
. I can do the following (_a
needs to be mutable):
let mut _a: Option<String> = Some(String::from("foo"));
if let Some(ref mut aa) = _a {
aa.push_str("_");
println!("aa: {:?}", aa)
}
Now let's say that I have two Option<String>
values that I want to pattern match over.
let _b: Option<String> = Some(String::from("bar"));
let _c: Option<String> = Some(String::from("baz"));
if let (Some(ref mut bb), Some(ref mut cc)) = (_b, _c) {
bb.push_str("_");
cc.push_str("_");
println!("bb: {:?}, cc: {:?}", bb, cc);
}
Strangely, I can use ref mut
in the patterns, even though neither _b
nor _c
are mutable, and I can mutate the strings. Why is that allowed here in this case? I'd expect this not to compile unless both _b
and _c
are declared as mutable similar to the first example above.
I think what may be happening is that a tuple is constructed in the pattern match, i.e. (_b, _c)
, and then some compiler magic allows the ref mut
on the pattern that is "bound" to this tuple. Is that correct?
Rust version:
rustc 1.41.1 (f3e1a954d 2020-02-24)