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

我的Rust链表节点删除代码为何触发BorrowMutError?

Rust链表删除函数中的BorrowMutError问题解析

问题场景

你编写了一个基于Rc<RefCell>的链表节点删除函数,第一段代码运行时触发BorrowMutError panic,修改后的代码则正常工作。

出错的代码

pub struct ListNode<T: Copy> {
    val: T,
    pub next: Option<Rc<RefCell<ListNode<T>>>>,
}

pub fn remove<T: Copy>(node: &Rc<RefCell<ListNode<T>>>) {
    if node.borrow_mut().next.is_none() {
        return;
    }

    if let Some(next) = node.borrow_mut().next.take() {
        let new_next = next.borrow_mut().next.take();
        node.borrow_mut().next = new_next;
    }
}

修复后的代码

pub fn remove<T: Copy>(node: &Rc<RefCell<ListNode<T>>>) {
    if node.borrow_mut().next.is_none() {
        return;
    }

    let curr_next = node.borrow_mut().next.take();
    if let Some(next) = curr_next {
        let new_next = next.borrow_mut().next.take();
        node.borrow_mut().next = new_next;
    }
}

第一段代码的问题根源

问题出在if let表达式的可变借用生命周期上:

  • 在if let Some(next) = node.borrow_mut().next.take()这一行,node.borrow_mut()返回的RefMut<ListNode<T>>会持续整个if let表达式的作用域(包括后续的代码块)。
  • 当进入代码块执行node.borrow_mut().next = new_next时,你尝试再次对同一个RefCell进行可变借用,但此时之前的RefMut还未释放(if let作用域未结束),违反了RefCell"同一时间只能存在一个可变借用"的规则,直接触发BorrowMutError panic。

修复代码的核心逻辑

修改后的代码把node.borrow_mut().next.take()的结果赋值给局部变量curr_next:

  • 赋值完成后,node.borrow_mut()返回的RefMut会立即被销毁(无变量持有它),可变借用随之释放。
  • 后续代码块中再次调用node.borrow_mut()时,RefCell处于无借用状态,因此可以正常获取新的可变借用,完成节点替换操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:52:34