Ownership & Borrowing
- Each value in Rust has an owner.
- There can only be one owner at a time.
- When the owner goes out of scope, the value will be dropped. ( call
drop
) - At any given time, you can have either one mutable reference or any number of immutable references. (one writer or multiple readers)
- References must always be valid.
Rust won't allow double free or dangling pointer in safe mode.
fn borrow(b: &String) { println!("borrow -> {b}"); } fn mut_borrow(mb: &mut String) { *mb = "updated".to_string(); } fn move_msg(m: String) { println!("{m}"); } fn main() { let mut msg = String::from("hello"); borrow(&msg); println!("{msg}"); mut_borrow(&mut msg); println!("{msg}"); borrow(&msg); println!("{msg}"); move_msg(msg); // error here because msg was moved in above line println!("{msg}"); }
keywords
- borrow, move
- copy, drop
- dangling pointer
- double free
SUMMARY (from a reddit user)
The borrowing and ownership mechanism can be simplified down to:
- Passing a variable by value will move ownership, dropping the original variable from memory
- Passing a variable by mutable reference will keep the original variable, but allow you to modify the variable.
- You may only borrow a variable mutably once at a time, and you may not immutably borrow while mutably borrowing.
- You may have as many immutable borrows as you want, so long as you aren't modifying that value.
- You may mutably borrow a field in a struct, and then mutably borrow a different field in the same struct simultaneously, so long as you aren't also mutably borrowing the overall struct.
- You can use
Cell
andRefCell
to allow for mutably modifying an immutable field in a struct. - You may mutably borrow multiple slices from the same array simultaneously so long as there is no overlap.
- Safe memory practices means that instead of mutably borrowing the same variable in multiple places, you queue the changes to make in a separate location and apply them serially one after another.
From chatgpt
Ownership
- Every value in Rust has a single owner.
- When the owner goes out of scope, the value is automatically dropped (freed from memory).
- You can borrow a value from its owner, allowing you to use the value without taking ownership of it.
- When a value is borrowed, the original owner cannot modify the value until the borrow goes out of scope.
fn main() { let x = 5; // x is a new i32 value with the value 5 let y = x; // y is a new i32 value with the value 5 // x is no longer needed, so it is dropped println!("{}", y); // prints 5 }
Borrowing
There are two types of borrowing in Rust: immutable borrowing and mutable borrowing.
Immutable borrowing is done using the & operator. It allows you to use a value without changing it, but it does not allow you to modify the value.
fn main() { let x = 5; let y = &x; // y is an immutable borrow of x println!("{}", y); // prints 5 *y = 6; // error: cannot assign to immutable borrowed value }
Mutable borrowing is done using the &mut operator. It allows you to use and modify a value, but it requires that you have exclusive access to the value for the duration of the borrow.
fn main() { let mut x = 5; let y = &mut x; // y is a mutable borrow of x *y = 6; // ok: we can modify x through y println!("{}", y); // prints 6 }