In this lesson, you will learn how to modify data even when you only have an immutable reference to it, using the concept of "Interior Mutability."
The Borrow Checker Wall
Up until now, you have followed the rule that if you have an immutable reference (&T), the data is "locked" and cannot be changed. This is the cornerstone of Rust's safety: it prevents data races and unexpected state changes. However, there are times when your program logic requires you to modify a value while parts of your code believe they only have read-only access.
This is where Interior Mutability comes in.
Bypassing Rules, Not Breaking Them
Interior mutability is a design pattern that allows you to mutate data even when there are immutable references to that data. Types like Cell<T> and RefCell<T> achieve this by moving the borrow checking from compile-time (where the compiler stops you) to runtime (where the program keeps an eye on itself).
Think of it like a library. Usually, the librarian refuses to let you change a book if someone else is reading it. With interior mutability, the "book" (the data) is stored inside a special container that keeps track of how many people are currently looking at it. If you try to mutate it while someone else is reading, the program will trigger a panic at runtime rather than failing to compile.
use std::cell::Cell;
fn main() {
// We bind our value as immutable
let data = Cell::new(10);
// We can "change" the value even though 'data' is immutable
data.set(20);
println!("Value: {}", data.get());
}
By wrapping the value in a Cell, you are telling the compiler: "I take full responsibility for the safety of this data. If I try to violate the rules, stop the program immediately."
Interior mutability doesn't delete the borrow rules; it simply enforces them when the code is actually running, allowing for complex patterns like graphs or caches that the standard compile-time checker might otherwise reject as too risky.
Key Takeaway: Interior mutability allows us to modify data through an immutable reference by shifting borrow enforcement from compile-time to runtime.