<T>
Cell<T>
is a struct that contains a single private value of type T. You can get and set the field even if you don’t have mut access to the Cell itself.
- Cell::new(value): Creates a new Cell, moving the given value into it.
- cell.get(): Returns a copy of the value in the cell
- cell.set(value): Stores the given value in the cell, dropping the previously stored value. It's a safe way of bending the rules on immutability.
<T>
Like Cell<T>
, RefCell<T>
is a generic type that contains a single value of type T. Unlike Cell, RefCell borrows references to its T value. As Cell<T>
, RefCell<T>
uses runtime checks to manage borrowing, borrowing as mutable can invoke panic.
- RefCell::new(value): Creates a new RefCell, moving value into it.
- ref_cell.borrow(): Returns a shared reference to the value stored in ref_cell(
Ref<T>
)- ref_cell.borrow_mut(): Returns a mutable reference to the value stored in ref_cell(
Ref<T>
). This method panics if the value is already borrowed.- ref_cell.try_borrow(), ref_cell.try_borrow_mut(): Work just like borrow() and borrow_mut(), but return a Result
Rust's compiler strictly enforces lifetimes to prevent errors. However, Cell<T>
and RefCell<T>
rely on runtime checks, which can lead to issues not caught by the compiler.
use std::cell::RefCell;
let ref_cell: RefCell<String> = RefCell::new("hello".to_string());
let r = ref_cell.borrow(); // ok, returns a Ref<String>
let count = r.len(); // ok, returns "hello".len()
assert_eq!(count, 5);
// drop(r);
let mut w = ref_cell.borrow_mut(); // panic: already borrowed, but compiler can't detect
w.push_str(" world");
This code causes a runtime panic because ref_cell
is already borrowed. The compiler cannot detect this.
let mut my_string = "hello".to_string();
let ref_my_string = &my_string;
let mut_ref_my_string = &mut my_string; // cannot borrow `my_string` as mutable
println!("{:?}", ref_my_string);
The Rust compiler detects the borrow error at compile time.
While using Cell<T>
and RefCell<T>
, we need to be cautious as they bypass some of Rust's compile-time safety checks.