If you’ve heard anything about Rust, you’ve probably heard about ownership.
It’s the most important concept in the language because it’s how Rust guarantees memory safety without a garbage collector.
Don’t worry if this sounds complicated—we’ll take it slowly and explain with examples.
What Is Ownership? #
In Rust, every piece of data has exactly one owner.
- The owner is usually a variable that holds the data.
- When the owner goes out of scope, the data is automatically cleaned up.
This means you don’t have to manually free memory, and you don’t risk memory leaks. For example:
fn main() {
let name = String::from("Alice");
println!("Hello, {}", name);
} // name goes out of scope here, and memory is freed automatically
Code language: Rust (rust)In this example:
nameis the owner of the string"Alice".- When
mainends,namegoes out of scope, and Rust automatically frees the memory.
No free(), no garbage collector—Rust handles it.
Moving Ownership #
What happens if we assign one variable to another?
fn main() {
let name = String::from("Alice");
let other = name; // ownership moves to 'other'
// println!("{}", name); // ❌ ERROR: name is no longer valid
println!("{}", other); // ✅ works
}
Code language: Rust (rust)Here’s what happened:
nameowned"Alice".- When we assigned it to
other, ownership moved toother. nameis no longer valid.
Rust does this to prevent double freeing the same memory.
Cloning Instead of Moving #
If you want two independent copies, you can use .clone():
fn main() {
let name = String::from("Alice");
let other = name.clone(); // deep copy
println!("name: {}, other: {}", name, other);
}
Code language: Rust (rust)Now both name and other own their own copies of the string.
Borrowing with References #
Sometimes you don’t want to give away ownership—you just want to borrow the value. Rust lets you do this with &.
fn main() {
let name = String::from("Alice");
greet(&name); // borrow instead of move
println!("Back in main: {}", name); // ✅ still valid
}
fn greet(person: &String) {
println!("Hello, {}", person);
}
Code language: Rust (rust)In this example:
&namemeans “borrownamefor a moment.”- The function
greetuses the borrowed value, but doesn’t take ownership. nameis still valid afterward.
Why Ownership Matters #
The ownership system helps Rust prevent:
- Dangling pointers – using memory after it’s freed.
- Double frees – freeing memory twice.
- Data races – unsafe memory access across threads.
This is how Rust gives you safety and performance at the same time.
Summary #
- Every value in Rust has exactly one owner.
- When the owner goes out of scope, the value is freed.
- Assigning variables moves ownership.
- Use
.clone()if you need a copy. - Use
&to borrow data without taking ownership.