Core Concepts

Ownership and Borrowing

Understand Rust's unique ownership system — the key to memory safety without garbage collection.

The Ownership System

Rust's most unique feature. Three rules:

  1. Each value in Rust has a variable called its owner
  2. There can only be one owner at a time
  3. When the owner goes out of scope, the value is dropped (memory freed)

Move vs Copy

  • Move: When you assign a heap value to another variable, ownership moves. The original is no longer valid.
  • Copy: Stack types (integers, booleans, etc.) are copied instead of moved.

Borrowing (References)

References allow you to refer to a value without taking ownership.

  • &T — immutable reference (many allowed simultaneously)
  • &mut T — mutable reference (only one at a time, no immutable refs)

The Borrow Checker

The compiler enforces these rules at compile time. This is why Rust has no runtime memory errors.

Example

rust
fn main() {
    // Ownership and Move
    let s1 = String::from("hello");
    let s2 = s1;  // s1 is MOVED to s2
    // println!("{}", s1);  // ERROR: s1 no longer valid!
    println!("{}", s2);  // OK

    // Clone to make a deep copy
    let s3 = String::from("world");
    let s4 = s3.clone();  // explicit deep copy
    println!("{} {}", s3, s4);  // both valid

    // Copy types (stack-allocated)
    let x = 5;
    let y = x;  // x is COPIED, not moved
    println!("{} {}", x, y);  // both valid

    // Borrowing
    let s = String::from("hello");
    let len = calculate_length(&s);  // pass reference
    println!("'{}' has {} chars", s, len);  // s still valid!

    // Mutable borrowing
    let mut text = String::from("hello");
    change(&mut text);
    println!("{}", text);  // hello, world
}

fn calculate_length(s: &str) -> usize {
    s.len()  // just reading, no ownership taken
}

fn change(s: &mut String) {
    s.push_str(", world");  // modifying through mutable reference
}

// Lifetime annotations (explicit borrowing lifetimes)
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}
Try it yourself — RUST