FreezeBox<T>
is a container that can have two possible states:
* uninitialized: deref is not allowed.
* initialized: deref to a &T
is possible.
To upgrade a FreezeBox
to the initialized state, call lazy_init
.
lazy_init
does not require a mutable reference, making FreezeBox
suitable for sharing objects first and initializing them later.
Attempting to lazy_init
more than once, or deref while uninitialized
will cause a panic.
FreezeBox is compatible with no_std
projects (no feature flags needed).
It may be used in any environment with a memory allocator.
FreezeBox uses unsafe code internally. To ensure soundness, the unit tests pass under Miri, and the unsafe code is simple and easy to understand.
The minimum supported Rust version is 1.48.
This example creates a shared data structure, then circles back to initialize one member.
```rust use freezebox::FreezeBox; use std::sync::Arc;
/// A data structure that we will initialize lazily.
struct Resources {
name: FreezeBox
// Create an instance of the Resources
struct, which contains an
// uninitialized name
field.
let resources = Arc::new(Resources::default());
// Clone the Arc to emulate sharing with other threads, contexts, // or data structures. let res2 = resources.clone();
// Here we emulate another thread accessing the shared data structure. // NOTE: it's still our responsibility to ensure that the FreezeBox // is initialized before anyone dereferences it. // let func = move || { // explicit deref asserteq!(*res2.name, "Hello!"); // implicit deref allows transparent access to inner methods asserteq!(res2.name.len(), 6); };
resources.name.lazyinit("Hello!".tostring()); func(); ```
There are many similar crates out there: - lazystatic - oncecell - double-checked-cell