Rust链表删除元素时遭遇借用检查器错误求助
Rust链表实现中的借用检查器问题
我正在学习Rust编程语言,在实现基础数据结构(链表)时遇到了借用检查器的问题。
定义的Node结构体
#[derive(Debug)] pub struct Node { value: i8, next: Option<Box<Node>> }
正常工作的append函数
该函数负责遍历链表并在尾部插入新节点,实现如下:
fn append(&mut self, value: i8) { let mut leaf = self; loop { match leaf.next { None => break, Some(ref mut next) => { leaf = next } } } let new_node: Node = Node { value: value, next: None }; leaf.next = Some(Box::new(new_node)); }
报错的delete函数
我尝试实现按值删除节点的delete函数,逻辑是找到目标节点后更新引用跳过该节点,但编译报错。实现代码:
fn delete(&mut self, value: i8){ let mut current = self; loop { println!("{}", current.value); match current.next { None => break, Some(ref mut next_node) => { if next_node.value == value { println!("Need to drop: > {} <", next_node.value); println!("Next node is: > {:?} <", next_node.next); match next_node.next.take() { None => { println!("Nothing under next"); current = next_node; } Some(next_node_next) => { println!("Doing jump to next_next"); current.next = Some(next_node_next) } } } else { current = next_node } } } } }
编译错误信息
cannot assign to `current.next` because it is borrowed `current.next` is assigned to here but it was already borrowed
问题原因与修复方案
问题根源
报错是因为在Some(ref mut next_node)中对current.next进行了可变借用后,又试图直接修改current.next(current.next = Some(next_node_next))。Rust的借用规则不允许同一时间对同一变量既有可变借用又进行修改操作。
修复后的delete函数
fn delete(&mut self, value: i8) { let mut current = self; loop { println!("{}", current.value); // 先取出current.next的所有权,避免持续借用 match current.next.take() { None => break, Some(mut next_node) => { if next_node.value == value { println!("Need to drop: > {} <", next_node.value); println!("Next node is: > {:?} <", next_node.next); // 跳过要删除的节点,直接衔接后续节点 current.next = next_node.next.take(); } else { // 放回节点,继续遍历 current.next = Some(next_node); current = current.next.as_mut().unwrap(); } } } } }
修复说明
- 使用
current.next.take()将current.next的所有权临时取出,此时current.next变为None,解除了对它的持续借用。 - 若找到目标节点,直接将目标节点的
next赋值给current.next,跳过目标节点,目标节点会因失去所有权被自动销毁。 - 若不是目标节点,将节点放回
current.next,再通过as_mut()获取可变引用,继续遍历链表。
内容的提问来源于stack exchange,提问作者Oleg Tarasenko
相关产品推荐
相关产品推荐

