如何在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
相关产品推荐
相关产品推荐

