I'm working on a learning project, and I've got a bit where I want to modify the values of a certain set of variables. It's all the same code, so I wanted to make a list of these variables and then iterate through that list, operating on each. To explain, I made a minimal reproducer. The situation is like this:
fn add_ten_return_difference(n: &mut u32) -> u32 {
*n += 10;
20 - *n
}
fn main() {
let mut var1 = 1;
let mut var2 = 2;
let mut other_thing = 0;
other_thing += add_ten_return_difference(&mut var1);
other_thing += add_ten_return_difference(&mut var2);
println!("My numbers are now {} and {} and the other thing is {}",
var1, var2, other_thing);
}
(This prints My numbers are now 11 and 12 and the other thing is 17
, as expected.)
In the real code there are about a dozen variables which are structs rather than integers and the "other things" are more complicated, so it gets kind of crazy looking. Rather than have all of those duplicated lines, I want to loop through a list. This works for a read-only example:
fn just_return_difference(n: u32) -> u32 {
10 - n
}
fn main() {
let var1 = 1;
let var2 = 2;
let mut other_thing = 0;
for n in [var1, var2].iter() {
other_thing += just_return_difference(*n);
}
println!("My numbers are now {} and {} and the other thing is {}",
var1, var2, other_thing);
}
(Prints My numbers are now 1 and 2 and the other thing is 17
.)
... so I thought it'd be easy to make one where the vars are mutable. This leads to one of those rust-newbie situations where I'm fighting with the compiler.
I tried this:
fn main() {
let mut var1 = 1;
let mut var2 = 2;
let mut other_thing = 0;
for mut n in [var1, var2].iter() {
other_thing += add_ten_return_difference(&mut *n);
}
println!("My numbers are now {} and {} and the other thing is {}",
var1, var2, other_thing);
}
… but that tells me cannot borrow
*nas mutable, as it is behind a
& reference
, with the suggestion:
for mut n in [var1, var2].iter() { ----- help: consider changing this to be a mutable reference: `&mut u32`
… which then gets me
for &mut n in [var1, var2].iter() { ^^^^^^ ------------------- this expression has type `&{integer}` | types differ in mutability
So I thought oh, I see — duh and changed .iter()
to .iter_mut()
. But this tells me
type `{integer}` cannot be dereferenced.
I can change to for n in [var1, var2].iter_mut()
, and now the code compiles, but n
is only changed in the scope of the loop and var1
and var2
don't get altered.
Help me understand so I don't need to fight. How should I be doing this?