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

如何在Rust中为栈分配对象创建多个可变引用?

Rust 实现 C 中多结构体指向同一栈对象的逻辑

原 C 代码示例

typedef struct A { int i; } A;
typedef struct B { A* a; } B;
typedef struct C { A* a; } C;

int main(void)
{
  A a = { .i = 42 };
  B b = { .a = &a };
  C c = { .a = &a };
}

问题核心

原代码中栈分配的A对象被B和C的指针同时指向,但 Rust 的所有权规则禁止直接创建多个可变引用,需要调整实现方式适配语言的安全机制。


解决方案

1. 使用不可变引用(匹配原 C 代码只读场景)

原 C 代码未对A做修改操作,用不可变引用完全符合逻辑,Rust 允许多个不可变引用同时存在:

#[derive(Debug)]
struct A {
    i: i32,
}

#[derive(Debug)]
struct B<'a> {
    a: &'a A,
}

#[derive(Debug)]
struct C<'a> {
    a: &'a A,
}

fn main() {
    let a = A { i: 42 };
    let b = B { a: &a };
    let c = C { a: &a };

    println!("b's a: {:?}", b.a);
    println!("c's a: {:?}", c.a);
}

通过生命周期标注<'a>确保B和C的引用生命周期不超过a,避免悬垂引用。

2. 需要修改A时:使用内部可变性

如果要通过B或C修改A的值,可借助 Rust 的内部可变性类型Cell或RefCell,它们允许在持有不可变引用的同时修改内部数据:

use std::cell::Cell;

#[derive(Debug)]
struct A {
    i: Cell<i32>,
}

#[derive(Debug)]
struct B<'a> {
    a: &'a A,
}

#[derive(Debug)]
struct C<'a> {
    a: &'a A,
}

fn main() {
    let a = A { i: Cell::new(42) };
    let b = B { a: &a };
    let c = C { a: &a };

    b.a.i.set(100);
    println!("c's a i: {}", c.a.i.get()); // 输出 100
}
  • Cell适用于Copy类型(如i32),操作无需借用检查;
  • 非Copy类型可使用RefCell,它会在运行时检查借用规则,违反时触发 panic。

3. 使用裸指针(不推荐,仅兼容 C 风格)

如果要完全复刻 C 的裸指针逻辑,Rust 也支持,但会跳过安全检查,需手动保证内存安全:

#[derive(Debug)]
struct A {
    i: i32,
}

#[derive(Debug)]
struct B {
    a: *mut A,
}

#[derive(Debug)]
struct C {
    a: *mut A,
}

fn main() {
    let mut a = A { i: 42 };
    let b = B { a: &mut a };
    let c = C { a: &mut a };

    unsafe {
        (*b.a).i = 100;
        println!("c's a i: {}", (*c.a).i); // 输出 100
    }
}

注意:裸指针操作属于unsafe范畴,Rust 不会检查悬垂引用、数据竞争等问题,非必要不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:06:18