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);
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.
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.