Introduction
The Cell
class in Rust provides interior mutability, a design pattern that allows you to mutate data even when there are immutable references to that data. Unlike RefCell
, Cell
does not enforce Rust's borrowing rules at runtime and is intended for simpler data types that can be copied.
Using Cell
The Cell
class can be used to create a mutable data structure that can be safely accessed and modified. Here is a basic example:
use std::cell::Cell;
fn main() {
let data = Cell::new(5);
data.set(10);
println!("Value: {}", data.get());
}
// Output: Value: 10
Key Methods
Below are some of the key methods exposed by the Cell
class:
new
Creates a new Cell
containing the given value.
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
println!("Created Cell with value: {}", cell.get());
}
// Output: Created Cell with value: 5
get
Gets the current value of the Cell
.
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
let value = cell.get();
println!("Value: {}", value);
}
// Output: Value: 5
set
Sets the value of the Cell
.
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
cell.set(10);
println!("Updated value: {}", cell.get());
}
// Output: Updated value: 10
swap
Swaps the values of two Cell
instances.
use std::cell::Cell;
fn main() {
let cell1 = Cell::new(5);
let cell2 = Cell::new(10);
cell1.swap(&cell2);
println!("Cell1: {}, Cell2: {}", cell1.get(), cell2.get());
}
// Output: Cell1: 10, Cell2: 5
replace
Replaces the value of the Cell
with a new value, returning the old value.
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
let old_value = cell.replace(10);
println!("Old value: {}, New value: {}", old_value, cell.get());
}
// Output: Old value: 5, New value: 10
Example Usage
Example 1: Basic Usage
use std::cell::Cell;
fn main() {
let data = Cell::new(5);
data.set(10);
println!("Value: {}", data.get());
}
// Output: Value: 10
Example 2: Get and Set
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
cell.set(10);
println!("Updated value: {}", cell.get());
}
// Output: Updated value: 10
Example 3: Swapping Values
use std::cell::Cell;
fn main() {
let cell1 = Cell::new(5);
let cell2 = Cell::new(10);
cell1.swap(&cell2);
println!("Cell1: {}, Cell2: {}", cell1.get(), cell2.get());
}
// Output: Cell1: 10, Cell2: 5
Example 4: Replacing Value
use std::cell::Cell;
fn main() {
let cell = Cell::new(5);
let old_value = cell.replace(10);
println!("Old value: {}, New value: {}", old_value, cell.get());
}
// Output: Old value: 5, New value: 10
Example 5: Cell with Copy Types
use std::cell::Cell;
fn main() {
let cell = Cell::new((1, 2, 3));
let value = cell.get();
println!("Value: {:?}", value);
cell.set((4, 5, 6));
println!("Updated value: {:?}", cell.get());
}
// Output:
// Value: (1, 2, 3)
// Updated value: (4, 5, 6)
Considerations
Cell
only works with types that implement theCopy
trait. For non-Copy
types, useRefCell
instead.Cell
is not thread-safe. For thread-safe interior mutability, useMutex
orRwLock
.- Because
Cell
allows for interior mutability, it can be used to break Rust's borrowing rules, so use it carefully.
See Also
- RefCell - Provides interior mutability with runtime borrowing checks for non-
Copy
types. - Mutex - A mutual exclusion primitive useful for protecting shared data across threads.
- RwLock - A reader-writer lock for allowing concurrent reads or exclusive writes across threads.
- Arc - An atomic reference-counted smart pointer for shared ownership across threads.