Rust结构体成员引用其他成员的实现问题咨询
解决方案:Rust中Owner与Borrower的共享引用问题
问题根源
你最初的代码存在悬垂引用问题:new函数里的局部变量val生命周期仅局限于函数内部,Borrower持有它的引用,但Owner的value是val的拷贝。当new函数返回时,局部变量val被销毁,Borrower的引用指向已释放的内存,这违反了Rust的内存安全规则,因此编译器报错。
基于Rc的正确实现
使用Rc(引用计数智能指针)实现共享所有权是正确的方向,只需通过Deref操作获取内部值的引用,即可适配外部库的需求:
use std::rc::Rc; struct Owner { value: Rc<f32>, other: Borrower, } impl Owner { fn new() -> Self { let val = Rc::new(0.0); Self { value: val.clone(), other: Borrower::new(val), } } } struct Borrower { value: Rc<f32>, } impl Borrower { fn new(value: Rc<f32>) -> Self { // 通过&*value获取内部f32的不可变引用,满足外部库需求 external_library_needs_ref(&*value); Self { value } } } // 模拟外部库函数 fn external_library_needs_ref(_: &f32) {}
关键说明
Rc<f32>实现了Deref<Target=f32>,因此&*value会自动解引用为&f32,直接传递给需要该类型参数的外部库函数即可。Rc::clone仅增加引用计数,不会拷贝底层的f32值,性能开销极小。
若需可变引用的场景
如果外部库需要可变引用,需结合RefCell实现内部可变性(Rc本身仅支持共享不可变访问):
use std::rc::Rc; use std::cell::RefCell; struct Owner { value: Rc<RefCell<f32>>, other: Borrower, } impl Owner { fn new() -> Self { let val = Rc::new(RefCell::new(0.0)); Self { value: val.clone(), other: Borrower::new(val), } } } struct Borrower { value: Rc<RefCell<f32>>, } impl Borrower { fn new(value: Rc<RefCell<f32>>) -> Self { // 通过borrow_mut()获取可变引用,注意运行时会检查借用规则 let mut val_ref = value.borrow_mut(); external_library_needs_mut_ref(&mut *val_ref); Self { value } } } // 模拟需要可变引用的外部库函数 fn external_library_needs_mut_ref(_: &mut f32) {}
为什么不推荐外部存储值
将值放在结构体外部虽然能暂时解决问题,但会破坏代码的封装性,让所有权关系变得模糊,增加维护成本。使用Rc+Deref(或RefCell)的方案既能保证内存安全,又能维持结构体的封装性。
内容的提问来源于stack exchange,提问作者Aatos Tapper
相关产品推荐
相关产品推荐

