无法获取OnceLock底层数据的可变引用,编译报错E0596
问题:使用
OnceLock::get_mut()获取可变引用编译报错 代码示例
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[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`.
错误原因
CELL是不可变静态变量,而OnceLock::get_mut()方法需要接收&mut self(可变引用),Rust不允许直接对不可变静态变量进行可变借用,因此触发编译错误。
解决方案
要调用get_mut(),需要将CELL声明为static mut,并通过unsafe块访问(因为静态可变变量存在线程安全风险,Rust强制要求显式unsafe标记)。修改后的代码如下:
mod OL { use std::sync::OnceLock; static mut CELL: OnceLock<i32> = OnceLock::new(); pub fn set_cell_val(val: i32) { // 访问静态可变变量需要unsafe块 unsafe { CELL.set(val); } } pub fn get_mut_ref() -> &'static mut i32 { unsafe { CELL.get_mut().unwrap() } } } fn main() { OL::set_cell_val(42); let mut val = OL::get_mut_ref(); *val += 1; println!("{}", val); // 输出43 }
注意事项
- 使用
static mut意味着放弃Rust的线程安全保障,必须自行确保多线程环境下的访问安全(比如配合互斥锁)。 - 如果需要线程安全的可变访问,建议结合
Mutex或RwLock使用,例如static CELL: OnceLock<Mutex<i32>> = OnceLock::new();,这样可以避免直接使用static mut的unsafe操作。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

