Borrowing Rules
In this page:
The Core Borrowing Rule
Rust's borrowing rule is: at any given time, you can have either exactly one mutable reference, or any number of immutable references to a particular piece of data -- never both kinds simultaneously.
Example: The Core Borrowing Rule
fn main() {
let data = vec![1, 2, 3];
let r1 = &data;
let r2 = &data;
println!("{:?} and {:?}", r1, r2);
}
Login to try C/C++/Java/PHP code in the editor
Why the Rule Exists
This rule prevents data races at compile time: if code were reading a value while other code simultaneously changed it, the reader could see inconsistent or corrupted data. Rust simply disallows that possibility.
Example: Why the Rule Exists
fn main() {
let mut counter = 0;
{
let r = &mut counter;
*r += 1;
}
println!("counter = {}", counter);
}
Login to try C/C++/Java/PHP code in the editor
Non-Lexical Lifetimes
Modern Rust allows a reference's borrow to end as soon as it is last used, rather than only at the end of its enclosing block, making many previously-rejected patterns compile.
Example: Non-Lexical Lifetimes
fn main() {
let mut value = 5;
let r1 = &value;
println!("r1: {}", r1); // last use of r1
let r2 = &mut value; // fine: r1's borrow has ended
*r2 += 1;
println!("value: {}", value);
}
Login to try C/C++/Java/PHP code in the editor
References Must Always Be Valid
The borrow checker also guarantees a reference can never outlive the data it points to, eliminating dangling references entirely at compile time.
Example: References Must Always Be Valid
fn main() {
let owner = String::from("valid data");
let borrowed = &owner;
println!("{}", borrowed);
println!("owner is still around: {}", owner);
}
Login to try C/C++/Java/PHP code in the editor
- Trying to keep an immutable reference alive while also creating a mutable reference to the same data.
- Assuming borrow checker errors mean the code is fundamentally wrong, when often just reordering or shortening a scope fixes it.
- Forgetting that Non-Lexical Lifetimes let a reference's effective scope end at its last use, not at the end of the enclosing block.
- At any time, you can have either one mutable reference, or any number of immutable references, but not both.
- References must always be valid (point to data that has not been dropped) -- this is checked at compile time.
- The borrow checker enforces these rules statically, adding no runtime cost.
- Non-Lexical Lifetimes mean a reference's borrow ends at its last actual use, not necessarily at the end of its block.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: