Skip to content
Select theme

What is ownership in Rust?

Short answer: every value in Rust has exactly one owner, and when that owner goes out of scope the value is freed. That’s the whole rule. Moves, borrows, lifetimes and the errors you get from them are the same rule seen from different angles.

The Rust book states it as three sentences:

  • Each value in Rust has an owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

An owner is a binding: a let, a function parameter, a struct field, an element of a Vec. The value is the thing in memory — the text behind a String, the buffer a Vec<T> points at. For each one of those, the compiler can name a single place in the source that is responsible for freeing it.

flowchart LR
  O["let s = String::from(...)"] -->|"owns the buffer"| V["the heap buffer"]
  O -->|"borrowing"| B["a reader, not an owner"]
  O -->|"let t = s"| T["t becomes the owner"]
  O -->|"scope ends"| D["freed once"]

“Goes out of scope” means the closing brace. Leave a block and whatever it owned is dropped there, before the next statement runs — not at the end of the program, and not whenever a runtime decides to tidy up. Reassigning a variable that already holds a value drops the old one at that same moment. Values are dropped in reverse order of declaration, and inner scopes before outer ones.

That’s where the predictability comes from. The compiler knows where every value dies, so it can inline the free, and it can prove nothing else is still holding the value at that point.

Handing a value to somewhere else transfers the owner rather than duplicating it. The old name stops being usable, the value itself is untouched, and its destructor runs once — at the end of whichever scope ends up owning it.

A reference lets code use a value without becoming an owner. Take as many & as you like; the owner still frees the value, in exactly the place it would have without them.

  • Move errors like E0382 are the rule refusing to leave two owners in play.
  • Borrow errors are the rule saying a borrow can’t outlive the owner.
  • Lifetimes are how you write the owner’s scope down when the compiler can’t work it out from the code alone.