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
27KB
346 lines
lazy_rc – Lazy Rc<T> and Arc<T>
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))
}
}