← Back to Rust Course | Chapter 5: Ownership | Lesson 1 of 6

Ownership Rules

Ownership is Rust's rule that every piece of data has exactly one owner responsible for cleaning it up.
Syntax
rust
let owner = value;   // each value has one owner
let other = owner;   // ownership moves
// value is dropped when its owner goes out of scope

The Three Ownership Rules

Rust's ownership system rests on three rules: each value has one owner, there can only be one owner at a time, and when the owner goes out of scope, the value is dropped. These rules are enforced entirely at compile time.

Example: The Three Ownership Rules

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `owner`, set to `String::from("Rust")`
    let owner = String::from("Rust");
    // Print "{} is owned by this variable" to the console, substituting in `owner` (with a trailing newline)
    println!("{} is owned by this variable", owner);
}

Scope and Automatic Cleanup

When an owning variable goes out of scope, Rust automatically calls cleanup code to free its memory. This happens deterministically, without a garbage collector, right when the closing brace of its scope is reached.

Example: Scope and Automatic Cleanup

markup
// Entry point: execution of the program starts here
fn main() {
    {
        // Declare an immutable variable `temp`, set to `String::from("temporary")`
        let temp = String::from("temporary");
        // Print "Inside scope: {}" to the console, substituting in `temp` (with a trailing newline)
        println!("Inside scope: {}", temp);
    }
    // Print "temp has been dropped by now" to the console (with a trailing newline)
    println!("temp has been dropped by now");
}

Only One Owner at a Time

Because a value can only have one owner, assigning it to another variable transfers (moves) ownership rather than creating a second independent owner. This prevents two variables from both trying to free the same memory.

Example: Only One Owner at a Time

markup
fn main() {
    let a = String::from("hello");
    let b = a; // ownership moves from a to b
    println!("b owns the value: {}", b);
}

Why This Matters

These rules eliminate whole categories of bugs -- like double frees and use-after-free -- that are common in languages with manual memory management, without needing a garbage collector at runtime.

Example: Why This Matters

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `data`, set to `vec![1, 2, 3]`
    let data = vec![1, 2, 3];
    // Print "data is owned here and will be cleaned up automatically: {:?}" to the console, substituting in `data` (with a trailing newline)
    println!("data is owned here and will be cleaned up automatically: {:?}", data);
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assuming a value can have two independent owners at once -- Rust's core rule is exactly one owner at a time.
  2. Trying to use a variable after its value has been moved elsewhere, which the compiler rejects at compile time.
  3. Thinking ownership rules only apply to heap-allocated types like String -- they apply to all values, though simple types are also Copy.
Chapter Summary
  • Every value in Rust has exactly one owner variable at any given time.
  • When the owner goes out of scope, Rust automatically drops (frees) the value.
  • Ownership can be transferred (moved) to another variable, after which the original binding is no longer valid.
  • These rules are checked entirely at compile time, with zero runtime overhead.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.