Start learning free

LESSON 15 OF 348 · VARIABLES

Ownership and Moves in Rust in Rust

Lesson

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:

  1. Create s1 as String::from("AlgoCademy") and move it into s2, then print s2.
  2. Clone s2 into s3 and print both — cloning keeps the original alive.
  3. Create n1 = 7, assign it to n2, and print both — i32 is Copy, 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?


STEP 1 OF 8
    Ctrl + Enter to check

    Ownership And Moves in Rust

    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free