Ownership & Moves
One owner per value, moves, clone, Copy types and drop — the rules at the heart of Rust.
Ownership is the idea that makes Rust different. Three rules: every value has exactly one owner; when the owner goes out of scope, the value is dropped (its memory freed); and ownership can be moved to another variable or function, after which the old variable can no longer be used.
Moves, clones and copies
let b = a; moves the String: the heap data is not copied, b now owns it and a is invalid.
b.clone() makes a deep copy, so b and c own separate data.
take(c) moves c into the function; the String is freed when take returns.
Integers are Copy: let y = x; copies the bits and both stay usable.
The two Noisy values are dropped at the end of their scope, in reverse order of creation.
Copy vs move
let names = vec![...]; print_all(names); println!("{}", names.len()); // names was moved print_all(&names); // lend it instead println!("{}", names.len());
Passing a value moves it into the function. If you still need it, pass a reference (borrow) — next lesson.
After let b = a; where a is a String, why can't you use a?
Ownership of the heap buffer moved to b. If both were usable, both would try to free the same memory when they go out of scope (a double free).
Which types are Copy?
Simple stack-only types: integers, floats, bool, char, shared references (&T), and tuples/arrays made only of Copy types. Types owning heap memory or other resources are not.