Welcome to our deep dive into Rust's OnceCell and LazyCell! These powerful tools help manage shared state in a safe and efficient manner. Let's explore these concepts step-by-step.
OnceCell and LazyCell are part of the std::cell module in the Rust standard library. They are used to create cell types that hold a single value, but with special behavior.
These cell types help manage shared state in thread-safe and optimized ways. They can be used in various scenarios such as caching, logging, and singleton patterns.
To create a OnceCell, use the Cell::new function and pass once as an argument.
use std::cell::Cell;
let once_cell = Cell::new(None);To set a value in a OnceCell, call the set method. This method will panic if the cell already has a value.
once_cell.set(Some(42));To get a value from a OnceCell, call the get method. If the cell does not have a value, it will be initialized on first access.
let value = once_cell.get(); // Will return Some(42) after the set call aboveTo create a LazyCell, use the Cell::new function and pass lazy as an argument.
use std::cell::Cell;
let lazy_cell = Cell::new(|| {
println!("Initializing...");
42
});To get a value from a LazyCell, call the get method. The closure provided during creation will be executed if the cell does not have a value.
let value = lazy_cell.get(); // Will print "Initializing..." and return 42 on first accessUsing LazyCell, we can create a thread-safe singleton.
use std::sync::Once;
use std::cell::Cell;
use std::thread;
let singleton = Cell::new(|| {
println!("Initializing singleton...");
42
});
let init = Once::new();
let handle = thread::spawn(move || {
init.call_once(|| {
println!("Initializing singleton in another thread...");
singleton.set(100);
});
});
let value = singleton.get(); // Will return 42 initially
handle.join();
let value = singleton.get(); // Will return 100 after the thread finishes