Rust创建Space双向邻居时报expected struct but found mutable reference错误如何解决
问题原因
首先你的编译报错只是表面问题,核心是你用Box<Space>实现双向引用的设计本身不符合Rust的所有权规则:
Box<T>是独占智能指针,同一时间只能有一个所有者持有Box<T>的所有权。你需要让新邻居的left_neighbor指向当前Space,意味着当前Space会同时被上层调用者、新邻居的left_neighbor两个主体持有所有权,这在Rust安全规则里是不允许的。- 你当前的编译报错是因为
self是&mut Space可变引用,而Box::new()需要接收转移了所有权的Space实例,你不可能从可变引用直接得到一个独立的所有权实例(哪怕实现Clone也只是复制出新对象,不是指向原对象的引用)。
修复方案
双向链表这类多所有者共享+内部可变的场景,需要用Rc<RefCell<T>>组合实现:
Rc<T>用于支持多所有者共享所有权,只有引用计数清零才会释放底层对象RefCell<T>用于绕过编译期借用检查,在运行时校验借用规则,实现不可变引用下的内部可变性
完整可运行代码:
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] pub struct Space { left_neighbor: Option<Rc<RefCell<Space>>>, right_neighbor: Option<Rc<RefCell<Space>>>, } impl Space { pub fn new() -> Rc<RefCell<Self>> { Rc::new(RefCell::new(Self { left_neighbor: None, right_neighbor: None, })) } pub fn create_neighbor(self: Rc<RefCell<Self>>) { // 创建新邻居实例 let neighbor = Space::new(); // 新邻居的左指针指向当前对象,克隆Rc仅增加引用计数,不复制底层数据 neighbor.borrow_mut().left_neighbor = Some(self.clone()); // 当前对象的右指针指向新邻居 self.borrow_mut().right_neighbor = Some(neighbor); } } fn main() { let space1 = Space::new(); // 调用方法需要先克隆Rc避免转移所有权 space1.clone().create_neighbor(); // 验证双向引用是否生效 let space2 = space1.borrow().right_neighbor.as_ref().unwrap().clone(); let space2_left = space2.borrow().left_neighbor.as_ref().unwrap().clone(); println!("两个指针是否指向同一个Space对象:{}", Rc::ptr_eq(&space1, &space2_left)); }
补充说明
- 如果需要在多线程场景下使用,将
Rc替换为Arc、RefCell替换为Mutex/RwLock即可 - 注意循环引用问题:
Rc的循环引用会导致内存泄漏,如果你的链表支持删除节点,需要把其中一个方向的引用改成Weak<RefCell<Space>>弱引用来打破循环。
内容的提问来源于stack exchange,提问作者avs
相关产品推荐
相关产品推荐

