The bellow code creates a variable n
, then borrows n
and names it nref
, and then assigns a new value to the original n
. Assignment has happened after a borrow, but all is fine, and the code compiles.
//example 1
fn main() {
let mut n = 1;
let nref = &n;
n = 3;
}
The following code also compiles. This prints the value of the borrowed n
.
//example 2
fn main() {
let mut n = 1;
let nref = &n;
println!("{}", nref);
}
If I use a mutable borrow, I can even change the value of n
via nref
. This also compiles.
//example 3
fn main() {
let mut n = 1;
let nref = &mut n;
*nref = 4;
println!("{}", n);
}
However, this code does not compile:
//example 4
fn main() {
let mut n = 1;
let nref = &n;
n = 3;
println!("{}", nref);
}
It gives the error:
error[E0506]: cannot assign to `n` because it is borrowed
--> src\main.rs:5:5
|
4 | let nref = &n;
| -- borrow of `n` occurs here
5 | n = 3;
| ^^^^^ assignment to borrowed `n` occurs here
6 | println!("{}", nref);
| ---- borrow later used here
But in example 1
, we also assigned a value to n
after it had been borrowed, and it was fine. Why does using it after the assignment cause a problem? What bugs is this trying to avoid?
How can I safely achieve what I am trying to do in example 4
? I want a read only view of a number via it's reference, and I want to change the original, and then I want to look at the reference and see that the value has changed
edit
It seems I have to borrow n
again. The bellow works:
//example 5
fn main() { //line1
let mut n = 1; //line2
let mut nref = &n; //line3
n = 4; //line4
nref = &n; //line5
println!("{}",nref); //line6
}
Does this mean that when line 4 is executed, the borrow from line 3 is no longer valid? And hence I have to re-borrow it on line 5, so that I can use it on line 6?
What is going on under the hood here? I come from a C++ background, so in my head n
is stored at a memory location, and nref
points to that memory location. When the value of n
is changed, the memory location it is at does not change, so nref
will see the new value. However the above suggests that when we assign a new value to n
, the references to it are no longer valid. Does this mean it is acting more like Python, where everything is essentially a pointer to a bit of memory, and when you reassign something, you just repoint it at a new bit of memory?