Ownership & Borrowing
What is Ownership?
Section titled “What is Ownership?”Rust’s most distinctive feature is its ownership system — a set of rules the compiler enforces at compile time to guarantee memory safety without a garbage collector.
Every piece of memory in a Rust program is owned by exactly one variable at any given moment. When that variable goes out of scope, Rust automatically frees the memory. There is no runtime bookkeeping, no GC pauses, and no possibility of use-after-free or double-free bugs — the compiler rules them out entirely.
The Three Rules of Ownership
Section titled “The Three Rules of Ownership”- Every value in Rust has exactly one owner.
- When the owner goes out of scope, the value is dropped (memory is freed).
- Ownership can be transferred (moved) to a new owner — at which point the old owner is no longer valid.
These three rules are the entire foundation. Everything else in this module — moves, references, mutable borrows, and slices — flows from them.
fn main() { // Rule 1: one owner let s = String::from("hello");
// Rule 2: out of scope → dropped { let inner = String::from("inner"); println!("{}", inner); } // inner is freed here
// Rule 3: ownership transferred to t let t = s; println!("{}", t); // s is no longer valid here}What This Module Covers
Section titled “What This Module Covers”| Lesson | Concept |
|---|---|
| Ownership & Moves | Each value has one owner; assignment moves non-Copy types |
| References & Borrowing | Borrow a value with &T without taking ownership |
| Mutable Borrows | Modify through &mut T; the exclusive-access rule |
| Slices | Borrow a contiguous portion of a collection with &[T] or &str |
Why No Garbage Collector?
Section titled “Why No Garbage Collector?”A GC scans memory at runtime to find unreachable values and free them. This adds runtime overhead and introduces unpredictable pauses. Rust moves that work entirely to compile time: the compiler tracks every ownership transfer and scope exit and inserts the drop calls for you. The result is C-level performance with complete memory safety.
fn main() { // Rule 1: every value has exactly one owner let owner = String::from("owned by owner"); println!("Rule 1: {}", owner);
// Rule 2: when the owner goes out of scope, the value is dropped { let scoped = String::from("scoped value"); println!("Rule 2 inside scope: {}", scoped); } // scoped is dropped here — memory is freed println!("Rule 2: scoped is gone");
// Rule 3: ownership can be transferred (moved) let new_owner = owner; println!("Rule 3: now {}", new_owner); // 'owner' is no longer valid here}Compiling…