What's the difference between std::sync::{LazyLock, OnceLock}?

They looks did do the same thing: Initialize the inner value on the first access, and after that, we can get the reference to the inner value.
These are examples in the docs of std, where's difference?

static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
    println!("initializing");
    let mut m = HashMap::new();
    m.insert(13, "Spica".to_string());
    m.insert(74, "Hoyten".to_string());
    m
});
HASHMAP.get(...)

static COMPUTATION: OnceLock<DeepThought> = OnceLock::new();
COMPUTATION.get_or_init(|| DeepThought::new())

And I noticed there are some crates with simillar names such as once_cell crate.

Which I should use for reading a trivial config file?

I think the documentation is pretty clear about the differences between the two: OnceLock in std::sync - Rust

3 Likes

I think the docs of OnceLock summarize the difference quite well:

Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock doesn’t allow additional inputs to its function after you call LazyLock::new(|| ...).

OnceLock does not have the type of the callback used for initialization as part of its own type signature, but only in the signatures of the get_[mut_]or_[try_]init methods. So it basically can be initialized from multiple callbacks in your code, not just from the one you pass to LazyLock::new. OnceLock is thus more flexible because it can be conditionally initialized. I.e. you can do this:

static FOO: OnceLock<u8> = OnceLock::new();

fn main() {
    let some_condition = true;
  
    let foo = if (some_condition) {
        FOO.get_or_init(|| 0)
    } else {
        FOO.get_or_init(|| 1)
    };
}

which you can't do with LazyLock.


once_cell was so popular that the OnceCell types were integrated into the standard library as std::sync::OnceLock and std::cell::OnceCell, which got stabilized in Rust v1.70.0. If you need support for an older Rust version, you can use once_cell as a drop-in replacement.


If you can make your code work with LazyLock, I would prefer using it instead of OnceLock.

6 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.