The following test program would not compile:
fn f1( string: String) {
println!("{}", string );
}
fn f2( string: String) {
println!("{}", string );
}
fn main() {
let my_string: String = "ABCDE".to_string();
f1( my_string );
f2( my_string );
}
It generates the well-expected error:
11 | f1( my_string );
| --------- value moved here
12 | f2( my_string );
| ^^^^^^^^^ value used here after move
However, if you treat my_string with the to_string() method, the program compiles and works. to_string() should be a no-op method since my_string is a String already. However, this programs works fine.
fn f1( string: String) {
println!("{}", string );
}
fn f2( string: String) {
println!("{}", string );
}
fn main() {
let my_string: String = "ABCDE".to_string();
f1( my_string.to_string() );
f2( my_string.to_string() );
}
How does the rust theory explain this paradox?
The
ToString::to_stringmethod requires a&str, which isCopy, therefore it can be moved out while keeping ownership (because&T: CopyforT: ?Sized, see the documentation).On the other hand,
Stringdoes not implementCopy, which means once the value is moved, its ownership has been given away.