Explaining Rust Ownership with Fantasy Football
Published on 2025-04-29
Project Summary
An introductory guide to Rust Ownership.
Explaining Rust Ownership with Fantasy Football
It was the sixth round of our fantasy draft last season, and I was laser-focused on snagging D'Andre Swift. I had my mouse hovering over his name, ready to pounce the moment my turn came up. I'd built my entire draft strategy around him as my RB2. The perfect scheme.
Then Tony, picking just before me, called out "Swift!"
My stomach dropped. I frantically scrolled through my contingency options while the league chat exploded with laughing emojis at my expense. Our commissioner just smirked from across the room: "That's why you don't announce your picks before making them, genius."
That gut-punch moment of seeing your perfect plan collapse because someone else already owns what you wanted? That's exactly how Rust's ownership system works. And after five years of writing Rust code, I've found no better way to explain the concept to new developers than through fantasy football.
Fantasy Football: The Perfect Rust Analogy
Here's a simple Rust program showing how ownership works using our fantasy league as an example:
fn main() {
// Our competing fantasy teams
let mut my_team = Team::new("Tyler's Terminators");
let mut chris_team = Team::new("Chris's Champions");
// Draft day - I select my quarterback
let mahomes = Player::new("Patrick Mahomes", "QB");
// I draft Mahomes - my_team now OWNS this player
my_team.draft_player(mahomes);
// Chris tries this but it fails:
// chris_team.draft_player(mahomes); // Compiler error!
// Chris can view my player's stats without "owning" him
chris_team.scout_opponent_player(&my_team.players[0]);
// Week 3: I temporarily loan Chris a player due to injuries
{
let borrowed_player = my_team.loan_player_for_week(0);
chris_team.use_borrowed_player(borrowed_player);
// When this scope ends, the loan expires automatically
}
// I still have my full team after the loan ends
my_team.submit_lineup();
}
Why This Makes Sense
In our fantasy league, we have clear rules about player ownership that mirror Rust:
1. One Player, One Team
We'd have chaos if two teams could "own" the same player. Similarly, in Rust, each value has exactly one owner:
// I draft a player
let hill = Player::new("Tyreek Hill", "WR");
my_team.draft_player(hill);
// This line would cause a compiler error:
println!("Speed: {}", hill.speed); // Error: hill was moved!
The compiler stops me from accessing hill because ownership transferred to my_team. This prevents using data after it's been moved somewhere else.
2. Scouting Without Drafting
Chris can check the stats of my players without drafting them - just like Rust's borrowing:
// Chris checks my roster before our matchup
chris_team.scout_opponent_player(&my_team.players[0]); // Immutable borrow
dave_team.scout_opponent_player(&my_team.players[0]); // Multiple immutable borrows are fine
The & symbol means Chris is just "borrowing" information without taking ownership.
3. One-Week Loans
When I loaned Chris a player for a week due to his injury crisis, only one of us could control the player's destiny:
// Only ONE team can use a player in a given week
let loaned_rb = my_team.loan_player_for_week(2); // Mutable borrow
chris_team.use_borrowed_player(loaned_rb);
// This would fail during the loan period:
// my_team.start_player(2); // Error: already mutably borrowed!
In Rust, you can have either multiple immutable borrows OR one mutable borrow - never both simultaneously. This prevents data races.
4. End of Season? Memory Cleaned Up
When a scope ends in Rust, the memory gets cleaned up automatically:
{
// Mid-season trade block
let temp_player = Player::new("DeAndre Swift", "RB");
// If nobody drafts Swift, he gets "dropped" when this scope ends
}
// Swift is no longer accessible here - memory freed
Why I Love This Approach
After struggling to explain Rust's ownership to my team for months, the fantasy football analogy finally made it click. One junior dev told me: "Oh! So the compiler is basically our fantasy commissioner making sure nobody breaks the league rules!"
Exactly.
Ownership isn't some academic computer science concept - it's an intuitive system once you frame it in familiar terms. The next time you're struggling with borrowing checker errors, just ask yourself: "What would the fantasy commissioner do?"