Introduction
Rust promises something that sounds impossible: the speed of C and C++, without their most famous class of bugs — crashes and security holes caused by bad memory handling — and without a garbage collector pausing your program to clean up.
The trick is not magic. It is a set of rules, checked by the compiler before your program ever runs, called ownership.
Ownership: every value has one owner
In Rust, every value has exactly one owner — the variable that holds it. When the owner goes out of scope, the value is cleaned up automatically. Move the value to another variable, and the first one can no longer use it.
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 is moved, not copied
// println!("{}", s1); // Error: s1 no longer owns the value
println!("{}", s2); // Works
}
This looks annoying at first, and it is, briefly. But it eliminates an entire category of bugs: no two parts of a program can accidentally free the same memory, and nothing is used after it has been freed, because the compiler refuses to compile such code.
Borrowing: use it without owning it
Most of the time you do not want to give a value away — you just want to look at it. Borrowing lets a function use a value by reference, without taking ownership.
fn calculate_length(s: &String) -> usize {
s.len()
}
fn main() {
let s = String::from("hello");
let len = calculate_length(&s);
println!("{} is {} long", s, len); // s still works here
}
The & means "borrow this". The borrow checker enforces one rule: you can have either any number of read-only borrows, or exactly one writable borrow — never both at once. That single rule prevents data races, the bugs where two threads change the same data simultaneously.
The borrow checker is a teacher, not an enemy
Every Rust beginner fights the borrow checker. The secret experienced Rust developers share: the errors it reports are almost always real bugs that other languages would let through, to surface later as crashes in production. Fixing them at compile time is the whole point.
A good way to learn: write the code the way you would in another language, read the compiler's error carefully — Rust's error messages are famously helpful, often suggesting the exact fix — and adjust.
Where Rust shines
Rust is most at home where speed and reliability both matter: systems software, command-line tools, web servers, game engines, and WebAssembly (running compiled code in the browser). If a program must be fast and must never crash from memory errors, Rust is the strongest modern choice.
Takeaway
One owner per value, borrowing instead of copying when you only need to look, and a compiler that refuses unsafe code before it runs. Learn those three ideas, and Rust's reputation for difficulty starts to look like a reputation for thoroughness.
Originally published at https://practicaldevblog.blogspot.com/2026/10/rust-explained-memory-safety-without.html
Top comments (0)