I have enums that contain variables:
enum Asymmetric {
One(i32),
Two(i32, i32),
}
I want to change just one field of an already existing enum, without reassigning the entire enum. My code (playground):
// Does not compile
fn main() {
let two = Asymmetric::Two(4, 5);
let mut vec = vec![two];
foo(&mut vec[0]);
}
fn foo(baa: &mut Asymmetric) {
match baa {
&mut Asymmetric::Two(x0, x1) => {
x0 = 6;
}
_ => {}
}
}
This results in this error:
error[E0384]: re-assignment of immutable variable `x0`
--> src/main.rs:16:13
|
15 | &mut Asymmetric::Two(x0, x1) => {
| -- first assignment to `x0`
16 | x0 = 6;
| ^^^^^^ re-assignment of immutable variable
Thanks to "match ergonomics" (introduced in Rust 1.26, proposed here), you can write your code like this:
fn foo(baa: &mut Asymmetric) {
match baa {
Asymmetric::Two(x0, _) => {
*x0 = 6;
}
_ => {}
}
}
Since baa
is a mutable reference, but your pattern you're matching against (Asymmetric::Two(x0, _)
) is not, the name x0
is automatically bound as mutable reference.
You can also do it manually by using ref mut
. See this working code (playground):
fn foo(baa: &mut Asymmetric) {
match *baa {
Asymmetric::Two(ref mut x0, _) => {
*x0 = 6;
}
_ => {}
}
}
Some minor changes that are not related to your error, but which increase your code quality:
*
) the match
ed-on value instead of adding &
or &mut
to every pattern in the match_
as a name placeholder if you don't need to bind to that nameIn your case, you can simplify the code even further by using if let
. Whenever you are only interested in one match
-case, you should use if let
instead:
fn foo(baa: &mut Asymmetric) {
if let Asymmetric::Two(x0, _) = baa {
*x0 = 6;
}
}
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