✨
magic_static
Safe, global singletons initialized at program start.
Usage
Simply add magic_static
as a dependency in your Cargo.toml
to get started:
[dependencies]
magic_static = "*"
bare-metal
If your target doesn't support atomics or threads, enable the bare-metal
feature flag in your Cargo.toml
:
[dependencies]
magic_static = { version = "*", features = ["bare-metal"] }
Example
#[macro_use]
extern crate magic_static;
mod foo {
magic_static! {
pub(super) static ref MAGIC: usize = {
println!("Magic!");
42
};
pub(super) static ref BAR: std::sync::Mutex<()> = std::sync::Mutex::new(());
}
}
// You can also modularize your magic statics like so:
mod baz {
magic_static! {
pub(super) static ref MAGIC: usize = {
println!("Magic!");
42
};
pub(super) static ref BAR: std::sync::Mutex<()> = std::sync::Mutex::new(());
}
#[magic_static::main(
MAGIC,
BAR
)]
// The `magic_statics!` macro (NOT `magic_static!`) can generate this function for you
pub fn magic_static() {}
}
#[magic_static::main(
foo::MAGIC,
foo::BAR,
mod baz // This will initialize all magic statics in `baz`
)]
fn main() {
println!("Hello, world!");
}
lazy_static
Comparison to lazy_static
s are initialized on first-use and are targetted towards multithreaded applications.
Every time a lazy_static
is dereferenced, it must check whether it has been initialized yet. This is usually extremely cheap, and the resulting reference can be stored for use in hot loops (for example), but in some cases you may prefer no checks at all, i.e. a more lightweight solution.
magic_static
only performs these checks in debug builds, making it a more ergonomic choice for single-threaded and performance-critical applications.
The downside of using magic_static
is that you must manually initialize each magic_static
in your main
function or somewhere appropriate. See above for an example.