RefCell and Interior Mutability
RefCell lets you change a value even through a reference that's supposed to be read-only, but it checks the rules while your program runs instead of ahead of time.In this page:
Mutating Through RefCell
RefCell<T> lets you obtain a mutable reference to its inner data via .borrow_mut(), even when the RefCell itself is bound immutably, moving borrow checking to runtime.
Example: Mutating Through RefCell
use std::cell::RefCell;
fn main() {
let cell = RefCell::new(5);
*cell.borrow_mut() += 1;
println!("{}", cell.borrow());
}
Login to try C/C++/Java/PHP code in the editor
Runtime Borrow Checking
Unlike compile-time references, RefCell checks borrowing rules while the program runs: attempting two conflicting borrows at once causes a panic rather than a compile error.
Example: Runtime Borrow Checking
use std::cell::RefCell;
fn main() {
let cell = RefCell::new(String::from("hello"));
{
let borrowed = cell.borrow();
println!("Reading: {}", borrowed);
}
cell.borrow_mut().push_str(", world");
println!("{}", cell.borrow());
}
Login to try C/C++/Java/PHP code in the editor
Combining Rc and RefCell
Rc<RefCell<T>> is a common pattern that gives multiple owners shared access to the same data, while still allowing any of them to mutate it through the RefCell.
Example: Combining Rc and RefCell
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let shared = Rc::new(RefCell::new(0));
let clone_a = Rc::clone(&shared);
*clone_a.borrow_mut() += 10;
println!("Value: {}", shared.borrow());
}
Login to try C/C++/Java/PHP code in the editor
Why Interior Mutability Exists
Interior mutability provides an escape hatch for situations where Rust's strict compile-time borrowing rules are too rigid, such as a shared cache updated from multiple places, at the cost of moving some checks to runtime.
Example: Why Interior Mutability Exists
use std::cell::RefCell;
struct Cache {
value: RefCell<Option<i32>>,
}
fn main() {
let cache = Cache { value: RefCell::new(None) };
*cache.value.borrow_mut() = Some(42);
println!("{:?}", cache.value.borrow());
}
Login to try C/C++/Java/PHP code in the editor
- Borrowing a
RefCellmutably twice at the same time, which compiles fine but panics at runtime with a borrow error. - Using
RefCellwhen a plain&mutreference would work just as well, adding unnecessary runtime checking overhead. - Forgetting
RefCellalone doesn't allow sharing across owners -- it is usually combined withRcfor shared, mutable-looking data.
RefCell<T>allows mutating data even through an immutable reference, moving borrow checking from compile time to runtime..borrow()and.borrow_mut()return runtime-checked references, and violating borrowing rules causes a panic instead of a compile error.Rc<RefCell<T>>is a common pattern combining shared ownership with interior mutability.- Interior mutability should be used deliberately, since misuse turns compile-time errors into runtime panics.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: