How to replace lazy_static with the new OnceCell in Rust 1.70?
According to the release note of Rust 1.70, OnceCell struct is introduced as
Crates such as lazy_static and once_cell have filled this need in the past, but now these building blocks are part of the standard library, ported from once_cell's unsync and sync modules.
But how can I replace lazy_static with OnceCell? I have no idea because the example shown in the official documentation isn't related to global variables.
I have this lazy_static code (playground):
use std::collections::HashMap;
use lazy_static::lazy_static;
lazy_static! {
static ref MEM: HashMap<usize, usize> = {
let mut m = HashMap::new();
m.insert(0, 0);
m.insert(1, 1);
m.insert(2, 2);
m.insert(3, 6);
m.insert(4, 24);
m
};
}
fn factorial(i: usize) -> usize {
MEM[&i]
}
fn main() {
println!("{}", factorial(0)); //=> 0
println!("{}", factorial(1)); //=> 1
println!("{}", factorial(2)); //=> 2
println!("{}", factorial(3)); //=> 6
println!("{}", factorial(4)); //=> 24
}
And I rewrote this code instead to use OnceCell, which panics as MEM is not yet initialized (though I explicitly call MEM.set()) (playground):
use std::{cell::OnceCell, collections::HashMap};
const MEM: OnceCell<HashMap<usize, usize>> = OnceCell::new();
fn factorial(i: usize) -> usize {
MEM.get().unwrap()[&i]
}
fn main() {
let mut m = HashMap::new();
m.insert(0, 0);
m.insert(1, 1);
m.insert(2, 2);
m.insert(3, 6);
m.insert(4, 24);
MEM.set(m).unwrap();
println!("{}", factorial(0));
println!("{}", factorial(1));
println!("{}", factorial(2));
println!("{}", factorial(3));
println!("{}", factorial(4));
}
By the way, the nightly-only LazyCell worked like a charm (playground):
#![feature(lazy_cell)]
use std::{cell::LazyCell, collections::HashMap};
const MEM: LazyCell<HashMap<usize, usize>> = LazyCell::new(|| {
let mut m = HashMap::new();
m.insert(0, 0);
m.insert(1, 1);
m.insert(2, 2);
m.insert(3, 6);
m.insert(4, 24);
m
});
fn factorial(i: usize) -> usize {
MEM[&i]
}
fn main() {
println!("{}", factorial(0));
println!("{}", factorial(1));
println!("{}", factorial(2));
println!("{}", factorial(3));
println!("{}", factorial(4));
}