String type, move vs borrow (newb)


#1

Still unclear about some of the nuances of move and borrow. This is from The Book:

let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
  1. Why is s1 a move? It sort of makes sense because let x = some other variable is a move. But what gets moved into s3 is a concatenated string, not s1. I’m thinking that s1 is moved into some concatenation function, concatenated with &s2 and moved out (returned) of the function passing ownership to s3.
  2. what is the reasoning for not allowing s3 = &s1 +&s2? ( generates error [E0369]: binary operation + cannot be applied to type `&std::string::String’). I’m guessing that ‘+’ is only defined for a String and a &String but this seems weird. I can’t come up with a logical reason for not having &String + &String defined.
  3. OK. Fine. Accepting s1 gets dropped and can’t be used, what if I want do reuse it? Something like:
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = String::from("Bob");
let s4 = s1 + &s2;
let s5 = s1 + &s3; // NOPE!! Can't reuse s1
println!("{} {}.",s4,s5)

#2

Well, taken from the doc page for string

This consumes the String on the left-hand side and re-uses its buffer (growing it if necessary). This is done to avoid allocating a new String and copying the entire contents on every operation, which would lead to O(n^2) running time when building an n -byte string by repeated concatenation.

The string on the right-hand side is only borrowed; its contents are copied into the returned String .


Well, remember that Strings are Clone and therefore you can use something like the following:

let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = String::from("Bob");
let s4 = s1.clone() + &s2;
let s5 = s1 + &s3; 
println!("{} {}.",s4,s5)

#3

The explanation from the doc page partially answers the question why not allow &s1 + &s2. There is no buffer to reuse since both refer to borrowed String buffers instead of an owned one. So &s1 + &s2 would need to create a new String. Right?


#4

Yes, logically you would then need to create a new string with .clone() if you have a &String or to_string() should you have a &str