How to Understand Referenced References?

I marked Error on the code A line in the wrong place. May I ask why there is an error here?
code A:

fn main() {
    let mut a = String::from("hello");   
    let mut b = &mut a;
    let c = &b; 

    println!("b = {:?}", b);

    // **c = "world".to_string();  // Error
    println!("c = {:?}", c);
}

I marked Error on the code B line in the wrong place. May I ask why there is an error here?

code B:

fn main() {
    let mut a = String::from("hello");   
    let mut b = &mut a;
    let c = &mut b; 

    // println!("b = {:?}", b); // Error

    **c = "world".to_string(); 
    println!("c = {:?}", c);
}

A: you can't mutate through a shared reference.
B: as mutable references are not allowed to overlap, you can't use a mutable reference while its referent is re-borrowed.

But all of this is very basic. Please read The Book. Users on this forum can't be expected to explain the basics for every person all the time.

1 Like

But thses are referenced reference.

I don't know what that means. you are either using some concepts foreign to rust, or you are just inventing your own terminology.

For the first example: an immutable reference to a mutable reference doesn't give you mutable access. You need a mutable reference to a mutable reference for that.

For the second example: references to references are not special, like any other type when you have a mutable reference (c) to some value (b) and use the value (the print of b) then the mutable reference becomes invalid and can't be used again.

1 Like

Yes, and?

The reason A doesn't work isn't so much that the & reference is immutable, rather it's because the & reference is shared. Once you have a shared reference, the compiler prevents you from modifying anything behind it (even indirectly) because if you have multiple places that can modify the same thing, it leads to problems.

For example, this is allowed, even though b is immutable:

    let mut a = String::from("hello");   
    let b = &mut a;
    *b = String::from("world");

But with shared references, the compiler wants to prevent you from doing things like this:

    let mut a = String::from("hello");   
    let mut b = &mut a;
    let c1 = &b; 
    let c2 = &b;
    // Not cool: inconsistent modifications via independent references.
    **c1 = String::from("world1");
    **c2 = String::from("world2");
1 Like

This is not the ethos of URLO. By all means point people to the book, but please don't admonish them for asking questions about the basics or that have been asked before.

1 Like