Every value in Rust has exactly one owner — the variable that is responsible for it. When the owner goes out of scope, the value is cleaned up automatically. This is how Rust manages memory without a garbage collector, and it is the single most important idea in the language.
The surprising part: assigning a String to another variable moves it. The new variable becomes the owner, and the old variable is dead — you are not allowed to touch it anymore.
Moving a value:
let s1 = String::from("AlgoCademy");
let s2 = s1; // the String MOVES from s1 into s2
println!("s2 = {}", s2); // OK — s2 owns it now
After let s2 = s1; there is still only one copy of the text in memory — it just has a new owner. Nothing was duplicated, which makes moves very cheap.
The trap — using a variable after it moved:
If you try to use s1 after the move, the program does not even compile:
let s1 = String::from("AlgoCademy");
let s2 = s1;
println!("s1 = {}", s1); // ← using the OLD owner
The compiler stops you with this error:
error[E0382]: borrow of moved value: `s1`
--> main.rs:4:25
|
2 | let s1 = String::from("AlgoCademy");
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 | let s2 = s1;
| -- value moved here
4 | println!("s1 = {}", s1);
| ^^ value borrowed here after move
|
help: consider cloning the value if the performance cost is acceptable
|
3 | let s2 = s1.clone();
| ++++++++
Read it bottom-up: s1 was moved on line 3, so line 4 may not use it. The compiler even suggests the fix: if you really need two copies, call .clone() — it duplicates the data for real, and both variables stay usable.
Copy types — the exception:
Simple fixed-size types like i32, f64, bool and char implement the Copy trait. Assigning them just copies the bits, so the original stays valid:
let a = 7;
let b = a; // copied, not moved
println!("{} {}", a, b); // both fine — prints: 7 7
Assignment
Follow the Coding Tutorial and prove all three rules to yourself:
- Create
s1asString::from("AlgoCademy")and move it intos2, then prints2. - Clone
s2intos3and print both — cloning keeps the original alive. - Create
n1 = 7, assign it ton2, and print both —i32isCopy, so nothing moves.
The expected output is:
s2 = AlgoCademy
s2 = AlgoCademy, s3 = AlgoCademy
n1 = 7, n2 = 7
Hint
If the compiler says borrow of moved value, ask yourself: who owns this value right now?
Free plan: 30 tutor messages. Premium is unlimited.