Part 1 · 2 chapters · ~12 min

Ownership, Borrowing and Lifetimes

Ownership and drop, moves and Copy types, shared and mutable borrows, the borrow checker's rule ("many readers or one writer"), slices, lifetimes and elision, common borrow-checker errors and how to restructure code, Clone and when it is fine, and smart pointers (Box, Rc, Arc, RefCell).

3

The rules

code
let s = String::from("ac_1");
let t = s;                          // move
// println!("{s}");                 // error[E0382]: borrow of moved value: `s`

fn len(x: &String) -> usize { x.len() }          // borrow: caller keeps ownership
fn push_zero(x: &mut Vec<i64>) { x.push(0) }     // exclusive mutable borrow

let mut v = vec![1, 2, 3];
let first = &v[0];
// v.push(4);                       // error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
println!("{first}");                // (push could reallocate and leave `first` dangling: Rust refuses)

fn longest<'a>(a: &'a str, b: &'a str) -> &'a str { if a.len() >= b.len() { a } else { b } }
OWNERSHIP AND BORROWING
one owner, many readers or one writer, and no dangling references
owner: let s = String::from("ac_1")move: let t = ss is no longer usable&s shared borrowsmany readers at once&mut s exclusive borrowone writer, no readerslifetimesborrows cannot outlive the owner
swipe the figure sideways, or tap expand for full screen
1/5
one owner
Every value has exactly one owner. When the owner goes out of scope, the value is dropped (freed) automatically: no garbage collector and no manual free.
one owner; dropped at end of scopeno GC, no free()
4

Working with the borrow checker

situationtool
need a copy and it is cheap or rare.clone(): fine, especially while learning
a value on the heap with one ownerBox<T>
shared ownership in one threadRc<T> (+ RefCell<T> for runtime-checked mutation)
shared ownership across threadsArc<T> (+ Mutex<T> or RwLock<T>)
self-referential graphsindices into a Vec (arenas) instead of references
"cannot borrow as mutable" inside a looprestructure: collect changes first, apply after; or use indices

The borrow checker's errors are precise and usually suggest the fix. The learning curve is real (weeks, not days), and it is front-loaded: once the model clicks, it guides designs toward clear ownership, which is good design in any language.