简体   繁体   中英

Why I can't borrow immutable reference of a mutable reference

let mut v = vec![1, 2, 3];
let r = &mut v;
let rr = &r;
r.push(4);
println!("{:?}, {:?}", r, rr);

Gives error:

error[E0502]: cannot borrow `*r` as mutable because it is also borrowed as immutable
   |
86 |     let rr = &r;
   |              -- immutable borrow occurs here
87 |     r.push(4);
   |     ^^^^^^^^^ mutable borrow occurs here
88 |     println!("{:?}, {:?}", r, rr);
   |                               -- immutable borrow later used here

I understand the concept of immutable reference can not be borrowed for *r , if there is already a borrowed mutable reference of *r . However, in this case I am trying to borrow immutable reference of r , not of *r .

A reference is just a variable, like any other variable.

If you replace the variable r with an integer, you should see why this isn't possible:

fn main() {
    let mut r = 10;
    let rr = &r;
    r += 2;
    println!("{:?}, {:?}", r, rr);
}
error[E0506]: cannot assign to `r` because it is borrowed
 --> src/main.rs:4:5
  |
3 |     let rr = &r;
  |              -- borrow of `r` occurs here
4 |     r += 2;
  |     ^^^^^^ assignment to borrowed `r` occurs here
5 |     println!("{:?}, {:?}", r, rr);
  |                               -- borrow later used here

Any mutable variable automatically becomes immutable while an immutable reference to it exists.

If that weren't the case, the owner of the rr variable couldn't rely on the fact that the content of rr never changes while he has the reference, which is one of the main points of immutable references. It doesn't just mean that you can't modify the variable, but you can also rely on the fact that no one else modifies it while you hold the reference.

So the pure existence of rr makes r temporarily immutable. r will automatically become mutable again once rr stops existing, but as you println.(/*.,*/, rr) later, you force rr to stay alive until then and you force r to be immutable. That's why the modification fails.

The fact that in your code r is a reference doesn't change anything about this language mechanism. In your code, if this wouldn't error, the value rr references would change while rr exists. And again, the fact that rr is an immutable reference guarantees that the content that rr is referencing won't change.


Remark: The way I worded 'mutability' in this answer is somewhat incomplete, as 'interior mutability' exists, but it was easier to describe it this way. In reality, the words 'mutability' and 'immutability' should be replaced with 'exclusive access' and 'non-exclusive access'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM