You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:52:35