The ownership system is a core concept of Rust for ensuring memory safety at compile time. Each variable has an owner. Only one owner of a resource can exist at any given time.
Ownership is transferred (moved) when assigned or passed to a function. After transfer, the previous owner can no longer use the value:
let s = String::from("hello"); let t = s; // s is no longer accessible
Rust also distinguishes between borrowing (references).
&T is a read-only reference (borrow).&mut T is a mutable reference (mutable borrow), but only one can exist at a time.With these rules, Rust guarantees that data races, use-after-free errors, and other resource management issues will not occur.
Can there be more than one mutable reference (&mut T) at the same time for one value? Why?
Answer: No, at any given moment there can be either any number of immutable references or only one mutable reference. This prevents data races. Example of incorrect code:
let mut s = String::from("hi"); let r1 = &mut s; let r2 = &mut s; // compilation error!
Story
In one multithreaded project, a developer tried to store references to a mutable buffer without using ownership, which led to crashes (use-after-free) when the buffer was freed before the reference was done being used. Rust did not allow such code to compile, forcing an architectural change.
Story
At the start of a large Rust project, programmers migrated code from C++. They attempted to blend outdated habits of working with "raw" pointers, leading to resource ownership errors and continual panic from the borrow checker until the ownership architectural issue was resolved.
Story
In a string parsing library, errors with double freeing of memory were avoided only due to Rust's strict ownership system. A similar library in C++ led to hard-to-track bugs and memory leaks.