How it works...

By invoking the lazy_static! macro [10, 21 and 29], we define a lazily initialized object in the current scope. Lazy here means created only the first time it is used.

Contrary to a let binding, its scope can also be the global scope [10]. A realistic example for this is creating a collection with a known content that is used by many functions, as the alternative would be to create it once and pass it around endlessly.

If your lazy_static consists of a Vec with content that is known at compile time, you can instead use a const array, as its construction is constant. In terms of code, this means you don't need to use this:
lazy_static!{
static ref FOO: Vec<&'static str> = vec!["a", "b", "c"];
}
Instead, you can use the following:
const FOO: [&str; 3] = ["a", "b", "c"];

Remember when, in Chapter 1, Learning the Basics; Querying with Regexes, we talked about how compiling Regexes is expensive and should be avoided? lazy_static! is ideal for this. In fact, the pattern of creating a local static regex in a function is so widespread that we included it in this example [29]:

fn extract_day(date: &str) -> Option<&str> {
lazy_static! {
static ref RE: Regex =
Regex::new(r"(d{2}).(d{2}).(d{4})")
.expect("Failed to create regex");
}
RE.captures(date)
.and_then(|cap| cap.get(1).map(|day| day.as_str()))
}

Lastly, you can also create a global mutable state with lazy_static objects [21]. As mentioned in earlier chapters, the excessive state is the root of many evils in software development and should be treated with care. There are very few cases where having such an object is justifiable, as it is almost always better to pass the object around. There are exceptions, however. Sometimes a program revolves around the manipulation of one specific dataset in memory and all involved actors want to access it. In these cases, it can be very cumbersome to pass an object to literally every function in your code. One possible, but still very rare, an example where this might happen, is when dealing exclusively with a list of active connections [21]:

lazy_static! {
static ref CLIENTS: RwLock<Vec<String>> = RwLock::new(Vec::new());
}

Note that, as the borrow checker is disabled for objects with 'static lifetimes (see the following There's more... section), we need to wrap our static in a parallel lock, such as RwLock or Mutex, to guarantee thread safety. You can read more about that in Chapter 7Parallelism and Rayon; Access resources in parallel with RwLocks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.2.225