Rc and RefCell for shared ownership with interior mutability
Marcus Chen
Jan 2026
1 tab
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
let data = Rc::new(RefCell::new(vec![1, 2, 3]));
let data_clone = Rc::clone(&data);
data_clone.borrow_mut().push(4);
println!("{:?}", data.borrow());
}
1 file · rust
Explain with highlit
When you need multiple ownership without threads, Rc<T> (reference counted) is the answer. It tracks the number of owners at runtime and frees the data when the count reaches zero. For mutability, combine it with RefCell<T>, which enforces borrowing rules at runtime instead of compile time. RefCell::borrow() and RefCell::borrow_mut() return guards that panic if the rules are violated. I use Rc<RefCell<T>> sparingly, mostly for graph-like data structures or observer patterns where compile-time borrow checking is too restrictive. The downside is runtime overhead and potential panics, so I prefer compile-time solutions when possible. This pattern only works in single-threaded contexts; for threads, use Arc<Mutex<T>>.