Concatenating strings implementation rationale


What is the rationale to allow this code?

let a = String::from("a");
let b = a + "c"

While changing parameters is now allowed

let c = "c" + a

Also a is moved and not copied in the first sample while it could do the same in second.

And adding two Strings neither works without borrowing and making copy instead of moving temporary:

let d =  String::from("x") + String::from("d");

This is not compiling.

let e = String::from("x") + &String::from("e");

This works but copies while it could move both temporaries.



Predictability. String + &str has already a growable buffer existing in String, and the second string can be appended to it by just copying the second string over.

&str + String is less obvious that now the second argument is used as the buffer, and the entire second string has to be copied inside the buffer to a new position in order to make space for the prefix. It’s suddenly a much less efficient way to append.



String + &str also may copy, it depends on length of &str.
I don’t see less obvious here.
Any programmer is aware of copying in such case.
The solution here according to the book is to use format!("{}{}", a,b) which is not better in terms of writing.

What about String + String ? Why shouldnt it compile ?
If you want to move use String + String, if you want to copy use String + &String