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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:18:04