Reference and borrowing

    let mut s = String::from("hello");
    let r1 = &s;
    println!("{} and {}", r1);
    println!("{} and {}", s);
    println!("{} and {}", r1); // error
    println!("{} and {}", s); // ok

Why use r1 variable again then raise an error but use s variable is ok

I am not sure what you mean here: in the code you gave, none of the println! lines compile (because it expects two arguments after the string, but you only give one).
However, the following compiles and run fine:

let mut s = String::from("hello");
let r1 = &s;
println!("{}", r1);
println!("{}", s);
println!("{}", r1);
println!("{}", s);

Maybe this code is missing some context ?

1 Like

Sorry my bad

Edit: The following is wrong. I was thinking in terms of a mutable borrow, i.e. let r1 = &mut s;

   let mut s = String::from("hello");
    let r1 = &s;
    println!("{} and {}", r1);    // r1 borrowed from s
    println!("{} and {}", s);    // You use s again, so compiler drops r1 before this
    println!("{} and {}", r1);    //r1 is no longer valid here because you indicated you wanted to use s
    println!("{} and {}", s);    //s is still valid

r1 would have continued to be valid until the end of the scope except your usage of s told the compiler to drop it sooner.

1 Like

@m51 The println! macro does not take ownership of its arguments, so it should be valid.

1 Like

My bad, that's what I get for not actually trying the code. I wasn't assuming println took ownership. I had some weird idea that you could not use the original variable until you let go of the borrow. Maybe I was thinking of a mutable borrow. I guess I don't know what I was thinking.

1 Like

Yep, I think a mutable borrow is where my thoughts were.

The following compiles of course:

fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    println!("{}", r1);
    println!("{}", s);
}

but this of course does not:

fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    println!("{}", r1);
    println!("{}", s);
    println!("{}", r1);
}
1 Like