π¦ Rust Ownership & Lifetimes (For Monkeys!)
π What is Ownership? (Rustβs Biggest Rule!)
Rust does not have garbage collection. Instead, it has ownership rules to manage memory automatically!
π‘ Rule #1: Every Value Has One Owner
fn main() {
let banana = String::from("π"); // banana owns this String
let monkey = banana; // Ownership MOVED to monkey!
// println!("{}", banana); // β ERROR! banana lost ownership!
println!("{}", monkey); // β
Works!
}
When banana
gives ownership to monkey
, it loses access to the banana! π΅
π‘ Rule #2: When the Owner Dies, the Value is Dropped
fn main() {
{
let food = String::from("π"); // food is created
println!("Monkey eats: {}", food);
} // food goes out of scope, and is DROPPED ποΈ
// println!("{}", food); // β ERROR! food is GONE!
}
When food
goes out of scope, Rust automatically cleans it up! π§Ή
π Borrowing (Sharing Bananas!)
Monkeys donβt like sharing, but Rust allows borrowing instead of moving ownership!
π‘ Rule #3: You Can Borrow Without Taking Ownership
fn eat(banana: &String) { // Borrowing (not moving)
println!("Monkey eats: {}", banana);
}
fn main() {
let banana = String::from("π");
eat(&banana); // β
Works! banana is still owned by main
println!("Banana is still here: {}", banana);
}
Borrowing (&
) allows you to use a value without owning it!
π« Rule #4: No Mutability Conflicts!
You can:
- Have multiple immutable references (readonly π§)
- OR only one mutable reference (write access βοΈ)
fn main() {
let mut banana = String::from("π");
let monkey1 = &banana; // Immutable borrow
let monkey2 = &banana; // Another immutable borrow
println!("Monkeys see: {} and {}", monkey1, monkey2); // β
Works!
// let monkey3 = &mut banana; // β ERROR! Can't mutate while others read!
}
fn main() {
let mut banana = String::from("π");
let monkey = &mut banana; // β
Allowed, only ONE mutable borrow
monkey.push_str("π"); // Modify banana!
println!("Monkey added more bananas: {}", monkey);
}
β³ Lifetimes (How Long Can You Borrow?)
Sometimes monkeys borrow bananas for too long! Rust checks lifetimes to make sure bananas donβt disappear while being borrowed! πβ³
π‘ Rule #5: Lifetimes Define How Long a Borrow is Valid
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s1.len() > s2.len() { s1 } else { s2 }
}
fn main() {
let banana = String::from("πππ");
let apple = String::from("π");
let best = longest(&banana, &apple);
println!("Best fruit: {}", best);
}
Here, longest<'a>
means both inputs and output share the same lifetime.
β What Happens When Lifetimes Are Wrong?
fn bad() -> &String { // β ERROR! No lifetime!
let banana = String::from("π");
&banana // β banana is DROPPED here!
}
The banana disappears before it can be returned! π¨
π Summary (Monkey Wisdom π)
- β Ownership moves when assigned to another variable β‘οΈ
- β Every value has one owner π‘
- β Borrowing (
&
) lets you use without owning π - β Multiple immutable or one mutable borrow allowed π¦
- β Lifetimes ensure borrowed values live long enough β³
Now go write some Rust without dropping your bananas! π΅π