Move Semantics
In this page:
Moving Ownership on Assignment
When you assign a String (or other heap-allocated, non-Copy type) to a new variable, Rust moves the underlying data's ownership rather than copying it, and invalidates the original variable.
Example: Moving Ownership on Assignment
fn main() {
let original = String::from("Rustacean");
let moved = original;
println!("moved holds: {}", moved);
}
Login to try C/C++/Java/PHP code in the editor
Moves Happen on Function Calls Too
Passing a non-Copy value into a function moves ownership into that function's parameter. After the call, the caller's variable is no longer valid unless the value is returned back.
Example: Moves Happen on Function Calls Too
fn take_ownership(s: String) {
println!("Function now owns: {}", s);
}
fn main() {
let text = String::from("hello");
take_ownership(text);
println!("text was moved into the function");
}
Login to try C/C++/Java/PHP code in the editor
Getting a Value Back by Returning It
A function can return ownership of a value back to the caller, letting you keep using it under a (possibly new) variable name after the call.
Example: Getting a Value Back by Returning It
fn process(s: String) -> String {
println!("Processing: {}", s);
s
}
fn main() {
let text = String::from("data");
let text = process(text);
println!("Back in main: {}", text);
}
Login to try C/C++/Java/PHP code in the editor
Why Rust Uses Moves Instead of Deep Copies
Copying large heap-allocated data every time it is assigned would be slow. Moves let Rust transfer ownership cheaply (just copying a pointer, length, and capacity) while the compiler guarantees only one owner uses that memory.
Example: Why Rust Uses Moves Instead of Deep Copies
fn main() {
let large_data = vec![1; 5];
let transferred = large_data;
println!("Transferred without deep copy: {:?}", transferred);
}
Login to try C/C++/Java/PHP code in the editor
- Trying to use a variable after moving its value into another variable or into a function, causing a compile error.
- Assuming assignment always copies data like it might in some other languages -- for heap types, assignment moves by default.
- Confusing a move with a shallow copy that leaves two usable references to the same data -- Rust invalidates the original.
- Assigning a non-
Copyvalue to another variable moves ownership; the original variable becomes invalid. - Passing a non-
Copyvalue into a function also moves it, unless the function takes a reference. - Using a moved-from variable is a compile-time error, not a runtime bug.
- Move semantics avoid the cost of deep-copying data while still preventing use-after-free.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: