Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. RefCell<T> / Cell<T>

RefCell<T> / Cell<T>

RefCell<T> and Cell<T> are smart pointers that provide interior mutability. They enforce Rust's borrowing rules at runtime rather than compile time, allowing you to mutate values through immutable references.

Syntax

use std::cell::{Cell, RefCell};

// RefCell: use for non-Copy types (String, Vec, etc.)
let r = RefCell::new(value);
let borrowed = r.borrow();       // Immutable borrow (&T)
let mut borrowed = r.borrow_mut(); // Mutable borrow (&mut T)

// Cell: use for Copy types (i32, bool, etc.)
let c = Cell::new(value);
c.set(new_value);
c.get();

Method List

MethodDescription
RefCell::new(v)Wraps the value v in a RefCell.
borrow()Returns an immutable borrow (Ref<T>). Panics if a mutable borrow is already active.
borrow_mut()Returns a mutable borrow (RefMut<T>). Panics if any other borrow is already active.
try_borrow()Returns Result<Ref<T>, BorrowError> without panicking on failure.
try_borrow_mut()Returns a mutable borrow as a Result type. Does not panic on failure.
Cell::new(v)Wraps a Copy value in a Cell.
cell.get()Returns a copy of the value (requires the Copy trait).
cell.set(v)Replaces the value. No borrow is needed to modify it.

Sample Code

use std::cell::{Cell, RefCell};

// A struct whose internal state can be mutated through an immutable reference
struct Counter {
    count: Cell<u32>,
    log: RefCell<Vec<String>>,
}

impl Counter {
    fn new() -> Self {
        Counter {
            count: Cell::new(0),
            log: RefCell::new(vec![]),
        }
    }

    // Internal state can be mutated even with &self (immutable reference).
    fn increment(&self, label: &str) {
        let n = self.count.get() + 1;
        self.count.set(n);
        self.log.borrow_mut().push(format!("{}: {}", label, n));
    }

    fn show(&self) {
        for entry in self.log.borrow().iter() {
            println!("{}", entry);
        }
    }
}

fn main() {
    let c = Counter::new();
    c.increment("a"); // a: 1
    c.increment("b"); // b: 2
    c.increment("c"); // c: 3
    c.show();

    println!("total: {}", c.count.get()); // total: 3
}

Overview

Rust's compile-time borrow checker is powerful, but there are cases where you need to mutate internal state through an immutable reference by design. RefCell<T> and Cell<T> provide this "interior mutability." Borrowing rules are checked at runtime rather than at compile time.

Cell is suited for lightweight Copy types, while RefCell is used for non-Copy types such as String or Vec. Both are single-threaded only.

Violating RefCell's borrowing rules — such as holding a mutable and an immutable borrow at the same time — results in a runtime panic, not a compile error. If the borrow boundaries are unclear, use the safer try_borrow() family of methods.

If you find any errors or copyright issues, please .