What is the difference between
let y = &mut 5;
*y += 1;
let x = *y + 1;
and
let mut y = 5;
y += 1;
let x = y + 1;
They return the same result via println!
, but I can't decide which one is preferable.
What is the difference between
let y = &mut 5;
*y += 1;
let x = *y + 1;
and
let mut y = 5;
y += 1;
let x = y + 1;
They return the same result via println!
, but I can't decide which one is preferable.
Given your simple example of binding a variable to one or the other, then calling println!
locally, there really isn't much difference in the result (as you've noted).
A mutable value vs a mutable reference becomes more clear when you cross function boundaries. Have a look at this code:
fn main() {
let mut x = &mut 5;
do_work(x);
println!("{}", x);
}
fn do_work(n: &mut u32) {
*n += 5;
}
What do you think it prints? Here it is on the playground
Now look at this code:
fn main() {
let mut x = 5;
do_work(x);
println!("{}", x);
}
fn do_work(mut n: u32) {
n += 5;
}
What do you think this prints? Here it is on the playground
The answers are:
The top code block prints 10
. The bottom code block prints 5
.
Using the mutable reference means you're referencing the place in memory where the variable x
is stored. Across function boundaries, you're able to change the value stored in memory there. When the method returns and println!
hits.. the value of x
is updated.
In this specific example, x
is a u32
, which implements the Copy
trait. When you pass x
into the do_work
method, a copy of x
is made. In the body of the do_work
method, n += 5
adds 5 to the copy .. and does not reference the original block of memory at all.
...can't decide which one is preferable.
That depends entirely on use-case. Do you need to reference the original memory when crossing a function boundary? If you have marked your variable as mutable, there is a high chance that you do want to reference the original memory in the hopes of updating it. In that case, you would use a mutable reference. If you're just mutating a variable locally within a function.. then you won't require a reference.