Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Ownership and Borrowing  ›  Lesson

The Ownership Rules

Ownsership Rules & Memory Safety 15 minEvery value has exactly one owner, assigning or passing a heap-owning value moves it to a new owner, and the value is dropped when its owner goes out of scope.

The Ownership Rules

Two librarians both think they are responsible for returning the same book to the shelf. Either they bump into each other or one finds the book already gone. Rust's heap has the same problem, and ownership solves it with three short rules the compiler enforces on every line.

The rule

One owner at a time; assignment moves; the owner leaving scope drops the value.

  1. Each value has an owner, the variable holding it.
  2. There is only one owner at a time.
  3. When the owner goes out of scope, the value is dropped (for a String, its heap text is freed).

Rule 2 has a big consequence. Assigning a String, or passing it to a function, moves it:

let title = String::from("Night Garden");
let copy = title;            // ownership moves to copy
println!("{title}");         // error[E0382]: borrow of moved value: `title`

Only the 24-byte record (pointer, length, capacity) was copied; the heap text was not. If both names stayed valid, both would free the same text at the end of scope. So the compiler treats title as moved: from that line on, any use of it is an error.

Functions work the same way:

fn shelve(book: String) { /* ... */ }   // book dropped at the end

let title = String::from("Night Garden");
shelve(title);               // moved into the function
// title cannot be used here

A function can hand ownership back by returning the value.

Two escapes:

  • clone() makes a real, separate copy of the heap data. It costs time and memory, so Rust makes you ask for it.
  • Copy types are duplicated on assignment instead of moved. These are simple fixed-size values: all integers, floats, bool, char, and tuples or arrays made only of them. let a = 5; let b = a; leaves both usable.

The shortcut

At every = and every function call, ask: "Does this type own heap data?" Yes → it moves, and the old name is dead. No (it is Copy) → it is duplicated, both live.

Tracing a loan through the programStep 1 of 4
  1. Create

    let title = String::from("Night Garden"); title owns the text.

The trap is fixing every move error with .clone(). It compiles, but it copies data you may only need to read. The next lesson shows the usual fix: borrowing.

Drills

Answer fast — trust the rule.

quick drill

What happens with let a = String::from("Iron Tides"); let b = a; println!("{a}");?

quick drill

What happens with let a = 288; let b = a; println!("{a}");?

quick drill

After calling shelve(title) where fn shelve(book: String), can you still use title?

quick drill

Which of these types is Copy?

quick drill

Why does Rust move a String instead of copying it on assignment?

Remember

  • One owner at a time; assignment and passing move heap-owning values; leaving scope drops them.
  • Ask "does it own heap data?" Yes → move, no (Copy) → duplicate.
  • Trap: cloning to silence the compiler when a borrow would do.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhy is `title` gone?

Explain why this fails to compile, and give two different ways to fix it: let title = String::from("Night Garden"); let copy = title; println!("{title}");. Then explain why the same code with let pages = 288; works.