lazy_static is a very popular crate. Years ago, it had no better alternatives for certain tasks. But today, are there still any reasons to choose lazy_static
over OnceCell
(from the standard library, as of Rust 1.70), the once_cell crate, or the upcoming LazyLock
?
Are there still reasons to use lazy_static?
9.5k views Asked by at54321 AtThere are 2 answers
If you need the code to run on #![no_std]
platforms that do not have OS-level support for blocking, and guarantee that the initialization routine is only executed once, you may still need to use lazy_static
. As per the once_cell
documentation :
Does this crate support
no_std
?Yes, but with caveats.
OnceCell
is a synchronization primitive which semantically relies on blocking....Waiting fundamentally requires OS support.... You could make code to compile by blindly using pure spinlocks, but the runtime behavior would be subtly wrong.
once_cell
achieves no_std
support using either the race
or critical-section
features. race
only supports platforms with atomic pointers, and risks calling the initialization routine multiple times across different threads. critical-section
requires specific hardware and/or OS support from the critical_section crate.
On the other hand, lazy_static
's no_std
implementation uses spinlocks, so it should build for any platform without the risk of racy initialization. The author of the once_cell
crate has published an article explaining what is meant by "subtly wrong" behavior, which may need special care to avoid as well.
Note that these requirements are extremely specific and won't apply to most use-cases. once_cell
should be sufficient for everything else.
once_cell
andLazyLock
have a minimum support version of the compiler. For earlier versions of it you would probably want to stick tolazy_static
which has served it purpose pretty well when less features were available.