Singleton in Rust
Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code.
Singleton has almost the same pros and cons as global variables. Although they’re super-handy, they break the modularity of your code.
You can’t just use a class that depends on a Singleton in some other context, without carrying over the Singleton to the other context. Most of the time, this limitation comes up during the creation of unit tests.
By definition, Singleton is a global mutable object. In Rust this is a
static mut item. Thus, to avoid all sorts of concurrency issues, the function or block that is either reading or writing to a mutable static variable should be marked as an
For this reason, the Singleton pattern can be percieved as unsafe. However, the pattern is still widely used in practice. A good read-world example of Singleton is a
log crate that introduces
debug! and other logging macros, which you can use throughout your code after setting up a concrete logger instance, such as env_logger. As we can see,
env_logger uses log::set_boxed_logger under the hood, which has an
unsafe block to set up a global logger object.
- In order to provide safe and usable access to a singleton object, introduce an API hiding
unsafeblocks under the hood.
- See the thread about a mutable Singleton on Stackoverflow for more information.
Starting with Rust 1.63,
const, you can use global static
Mutex locks without needing lazy initialization. See the Singleton using Mutex example below.