I encountered the following (reduced) example:
enum Thing {
A { value: f32 },
B { value: f32 },
}
fn main() {
let mut thing = Thing::A { value: 0. };
let thing_mut_ref = &mut thing;
if let Thing::A {value} = thing_mut_ref {
*thing_mut_ref = Thing::B { value: value * 2.0};
}
}
The following does not compile because value is captured as a &mut f32, and thus does not support multiplying by 2.0.
What surprised me was that adding ref to the matched pattern suddenly makes it compile, i.e. captures by value (dereferences value):
enum Thing {
A { value: f32 },
B { value: f32 },
}
fn main() {
let mut thing = Thing::A { value: 0. };
let thing_mut_ref = &mut thing;
if let Thing::A {ref value} = thing_mut_ref {
*thing_mut_ref = Thing::B { value: value * 2.0};
}
}
I know ref for usually doing the opposite - stating that we do not want to capture by value. How does this explain what is going on here?
It does not in fact dereference but convert the mutable reference into a shared one.
And as you can see from the documentation of Mul it is implemented for &f32 and f32 but not for &mut f32
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With