liveBook · Manning

OnceCell

As explained in Learn Rust in a Month of Lunches

OnceCell is a type that permits a value to be initialized once and subsequently accessed without repeated initialization.

OnceCell stores a value that can be written exactly once and then accessed afterward. Create an empty cell with OnceCell::new(), initialize it with .set(), and retrieve the value with .get(). section 17.7.2

Unlike a fixed lazy static, OnceCell lets the program provide the value later. For example, a URL can be fetched in main and then used to build a global Logger. Choose the synchronized version when the value must cross threads; otherwise, use the unsynchronized version. section 17.7.2

use once_cell::sync::OnceCell;
use reqwest::Client;
use std::sync::Mutex;
 
#[derive(Debug)]
struct Logger {
    logs: Mutex<Vec<Log>>,
    url: String,
    client: Client,
}
 
#[derive(Debug)]
struct Log {
    message: String,
    timestamp: i64,
}
 
static GLOBAL_LOGGER: OnceCell<Logger> = OnceCell::new();
 
fn fetch_url() -> String {                               #1                
                                                         #2
    "http://somethingsomething.com".to_string()          #3
}
 
fn main() {
    let url = fetch_url();
 
    GLOBAL_LOGGER                                        #4
        .set(Logger {
            logs: Mutex::new(vec![]),
            url,
            client: Client::default(),
        })
        .unwrap();                                       #5
 
    GLOBAL_LOGGER                                        #6
        .get()                                           #7
        .unwrap()
        .logs
        .lock()                                          #8
        .unwrap()
        .push(Log {
        message: "Everything's going well".to_string(),
        timestamp: 1658930674,
    });
 
    println!("{GLOBAL_LOGGER:?}");                       #9
}

A complete example creates a thread-safe global OnceCell, sets a Logger after fetching its URL, reads it with get(), and adds a log entry. section 17.7.2

The same design is available through the standard library: std::cell::OnceCell is not thread-safe, while std::sync::OnceLock provides the thread-safe version. The surrounding code is almost unchanged. section 17.7.2

How Learn Rust in a Month of Lunches covers it

How deep it goes
Explains construction, set(), get(), synchronization choices, and a complete Logger example without descending into implementation internals.
Examples
Uses a global Logger whose URL is fetched later, then stores log entries protected by Mutex.
What it assumes
Assumes basic Rust types and methods while introducing one-time cells, synchronization choices, and delayed initialization.
What you can do after
Apply it via OnceCell or OnceLock to initialize and later access a global Logger value.
How it connects
Connects OnceCell with Cell, lazy_static, Mutex, and the standard-library OnceLock.

Also explained in

Compare how 2 books explain OnceCell →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.