I'm trying to get a mutable reference to the underlying data of OnceLock
using get_mut()
method, but getting error
mod OL {
use std::sync::OnceLock;
static CELL: OnceLock<i32> = OnceLock::new();
pub fn set_cell_val(val: i32) {
CELL.set(val);
}
pub fn get_mut_ref() -> &'static mut i32 {
CELL.get_mut().unwrap()
}
}
fn main() {
println!("Hello, world!");
}
Error
error[E0596]: cannot borrow immutable static item `CELL` as mutable
--> src/main.rs:11:9
|
11 | CELL.get_mut().unwrap()
| ^^^^^^^^^^^^^^ cannot borrow as mutable
For more information about this error, try `rustc --explain E0596`.
OnceLock
is a cell that is assigned once. By definition, after being assigned it can no longer change.
get_mut()
does exist, but it serves niche use cases and definitely not yours. OnceLock
is just not for you.
What you want is a Mutex
, or a RwLock
. They can be changed multiple times:
use std::sync::{Mutex, MutexGuard};
static VALUE: Mutex<i32> = Mutex::new(0);
pub fn set_value(val: i32) {
*value.lock().unwrap() = val;
}
// This is not a mutable reference, but it acts like one (e.g. it can be assigned into).
pub fn get_mut_ref() -> MutexGuard<'static, i32> {
VALUE.lock().unwrap()
}
If you want a changing value that is also lazily-initialized, you can use OnceLock<Mutex>
.