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

Rust如何无需运行时锁初始化存在循环引用的两个结构体?

解决方案

你的场景属于初始化完成后对象全生命周期只读的双向引用场景,不需要引入运行时锁,直接使用标准库提供的std::sync::OnceLock即可实现无锁的一次性内部可变性,完全匹配需求。

修改后可编译代码

use std::sync::{Arc, OnceLock};

struct First {
    // 用OnceLock替代Option,支持一次性内部写入,后续只读
    second: OnceLock<Second>,
}

struct Second {
    first: Arc<First>,
}

fn main() {
    // 先构建First的外壳,second字段暂未初始化
    let first = Arc::new(First {
        second: OnceLock::new(),
    });
    // 构建Second,直接持有First的Arc引用
    let second = Second {
        first: first.clone(),
    };
    // 完成First的second字段一次性赋值,确认是首次赋值直接unwrap即可
    first.second.set(second).unwrap();

    // 后续访问示例,无需任何锁操作
    println!("初始化完成:{}", first.second.get().is_some());
    println!("双向引用有效:{}", Arc::ptr_eq(&first, &first.second.get().unwrap().first));
}

方案说明

  • 无额外锁逻辑:OnceLock仅在初始化写入时做轻量级原子状态校验,后续读取完全是无额外开销的只读操作,全代码库不需要处理任何锁的获取、释放、错误处理逻辑。
  • 符合不可变约束:OnceLock的set方法仅允许调用一次,后续所有操作只能读取,标准库会直接保证你「初始化后全生命周期不变更」的要求,避免后续意外修改。
  • 完全安全:全程无需手动编写unsafe代码,所有操作都受编译器安全检查保护。

如果是单线程场景不需要跨线程共享,可替换为std::cell::OnceCell,性能开销更低,用法完全一致。

内容的提问来源于stack exchange,提问作者squidpickles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:57:02