Dynamic static at runtime

I have stumbled across something delightful, which bridges this gap, which I thought insurmountable. I have objects whose methods repeatedly need a few regexes, and I don't want to recompile. OTOH lazy_regex seems a bit overkill. What I came up with, are &'static to dynamic values. Since they only get accessed this way, and thus only created once, they outlive the references, even if they're less than static:

static REGEX_CACHE: OnceLock<[Regex; 2]> = OnceLock::new();

struct Item {
    a_b: &'static Regex,
    b_a: &'static Regex,
}

let [a_b, b_a] = REGEX_CACHE.get_or_init(||
    ["a+b", "b+a"].map(|re| Regex::new(re).unwrap()));
let item = Item {
    a_b,
    b_a
};
if let Some(caps) = item.a_b.captures("__aaab__") {
    println!("{caps:?}");
}
if let Some(caps) = item.b_a.captures("__bba__") {
    println!("{caps:?}");
}

I guess they'd even be safe under multithreading (not my use case.) But non-static static is startling!

The 'static annotation just means that the value will live forever. It doesn't say anything about when it was created.

5 Likes

I like to think of lifetimes as having end points but not start points.

A reference can be of type &'a T regardless of when the reference or the T was created; the type only requires that, once the reference exists, it points to a T that won't be mutated or dropped until 'a ends.

2 Likes

I can't find anything about this well guarded secret in the Rust Reference. It mostly ignores my query and answers about static items instead.

But at least Rust By Example knew.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.