#lazy-evaluation #initialization #rc-t #thread-safe #arc-t #lazy-arc

lazy_rc

Provides implementations of Rc<T> and Arc<T> with lazy initialization

4 releases

0.1.3 Jan 27, 2023
0.1.2 Jan 25, 2023
0.1.1 Jan 25, 2023
0.1.0 Jan 24, 2023

#68 in #initialization

24 downloads per month
Used in mtcp-rs

Custom license

27KB
346 lines

lazy_rc – Lazy Rc<T> and Arc<T>

Crates.io Unlicense

lazy_rc provides implementations of Rc<T> and Arc<T> with lazy initialization.

Crates.io:
https://crates.io/crates/lazy_rc

API Documentation:
https://docs.rs/lazy_rc/latest/index.html

Examples:
https://github.com/dEajL3kA/lazy_rc/tree/master/examples


lib.rs:

lazy_rc provides implementations of Rc<T> and Arc<T> with lazy initialization.

In other words, the "inner" value of an LazyRc<T> or LazyArc<T> instance is created when it is accessed for the first time, using the supplied initialization function. Initialization may fail, in which case the error is passed through.

Thread Safety

LazyRc<T> is single-threaded, because so is Rc<T>. Therefore, an LazyRc<T> instance can not be shared by multiple threads, and you can not use LazyRc<T> for static variables. However, it can be used for thread_local! variables.

LazyArc<T> is thread-safe, because so is Arc<T>. Therefore, an LazyArc<T> instance can be shared by multiple threads, and you can even use LazyArc<T> for global static variables.

Const Warning

Do not use LazyRc<T> or LazyArc<T> as a const value! That is because, in Rust, const values are "inlined", effectively creating a new instance at every place where the const value is used. This obviously breaks "lazy" initialization 😨

Example

use lazy_rc::{LazyRc, LazyArc};

static GLOBAL_INSTANCE: LazyArc<MyStruct> = LazyArc::empty();

thread_local! {
    static THREAD_INSTANCE: LazyRc<MyStruct>  = LazyRc::empty();
}

struct MyStruct {
   /* ... */
}

impl MyStruct {
    fn new() -> Result<Self> {
        /* ... */
    }

    /// Returns a thread-local instance that will be created on first access.
    /// If the initialization function fails, then an Error will be returned.
    pub fn instance() -> Result<Rc<Self>> {
        THREAD_INSTANCE.with(|lazy| lazy.or_try_init_with(Self::new))
    }
}

No runtime deps