When the owner leaves project scope, the value is freed (like the malloc → free properties in C)
Ownership can be moved (by transferring to another variable) or borrowed (temporarily accessed by a reference)
Example:
let s = String::from("hello");let t = s; // ownership moved from s to t// s can’t be used anymore
Borrowing
Instead of transferring ownership, you can borrow a value
Immutable borrow (&T) → You can read the value but not modify it.
Mutable borrow (&mut T) → You can modify the value, but only if no one else is borrowing it.
Rules:
A value can have any number of immutable borrows or exactly one mutable borrow, but neither simultaneously
A borrow can’t outlive its value
Example:
let mut x = 5;// Multiple immutable borrows are finelet r1 = &x;let r2 = &x;println!("{}, {}", r1, r2);// Only one mutable borrow allowedlet r3 = &mut x;let r4 = &mut x; // this would cause an error bc of two mutable borrows simultaneously
Lifetimes
Every reference has a lifetime (the scope of which the reference is valid)
The borrow checker ensures lifetimes line up so references can’t outlive their pointed data
Example:
let r;{ let x = 5; r = &x; }println!("{}", r);// x only exists inside the block and r exists outside, so r cannot be assigned a pointer to the value of x