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_string
method requires a &str
, which is Copy
, therefore it can be moved out while keeping ownership (because &T: Copy
for T: ?Sized
, see the documentation).
On the other hand, String
does not implement Copy
, which means once the value is moved, its ownership has been given away.