macro_rules! get_or_init {
($init:expr) => { ... };
}Expand description
Get a static reference to a generic singleton or initialize it if it doesn’t exist.
§Example
use std::collections::HashMap;
use std::ops::{Deref, DerefMut, Mul};
use std::sync::RwLock;
// The expensive function we're trying to cache using a singleton map, however,
// we want the user of the function to determine the type of the elements being
// multiplied.
fn multiply<T: Mul<Output = T>>(a: T, b: T) -> T {
a * b
}
fn multiply_with_cache<T: Mul<Output = T> + Send>(a: T, b: T) -> T
where
T: std::cmp::Eq,
T: Copy,
T: Sync + 'static,
(T, T): std::hash::Hash,
{
// This is a generic singleton map!!!
let map = generic_singleton::get_or_init!(|| RwLock::new(HashMap::new()));
let key = (a, b);
if map.read().unwrap().contains_key(&key) {
*map.read().unwrap().get(&key).unwrap()
} else {
let result = multiply(a, b);
map.write().unwrap().insert(key, result);
result
}
}
fn main() {
// This call will create the AnyMap and the HashMap<i32> and do the multiplication
multiply_with_cache::<u32>(10, 10);
// This call will only retrieve the value of the multiplication from HashMap<i32>
multiply_with_cache::<u32>(10, 10);
// This call will create a second HashMap< and do the multiplication
multiply_with_cache::<i32>(-1, -10);
// This call will only retrieve the value of the multiplication from HashMap
multiply_with_cache::<i32>(-1, -10);
}