Moves in Function Calls
When you pass a value to a function, the value is assigned to the function parameter. This transfers ownership:
fn say_hello(name: String) { println!("Hello {name}") } fn main() { let name = String::from("Alice"); say_hello(name); // say_hello(name); }
- With the first call to
say_hello,maingives up ownership ofname. Afterwards,namecannot be used anymore withinmain. - The heap memory allocated for
namewill be freed at the end of thesay_hellofunction. maincan retain ownership if it passesnameas a reference (&name) and ifsay_helloaccepts a reference as a parameter.
fn say_hello(name: &String) { println!("Hello {name}") } fn main() { let name = String::from("Alice"); say_hello(&name); say_hello(&name); }
- Alternatively,
maincan pass a clone ofnamein the first call (name.clone()).
fn say_hello(name: String) { println!("Hello {name}") } fn main() { let name = String::from("Alice"); say_hello(name.clone()); say_hello(name); }
- Rust makes it harder than C++ to inadvertently create copies by making move semantics the default, and by forcing programmers to make clones explicit.