Rust链表疑问
在解 leetcode 203. 移除链表元素 时,遇到一些生命周期和引用,再借用的一些疑问,此题非常简单,就是要删除给定数值的节点。先贴出来解法代码:
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
impl Solution {
pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> {
let mut head = head;
// 判断head是否为要删除的
while let Some(node) = head.as_ref() {
if node.val == val {
head = head.unwrap().next
} else {
break;
}
}
let mut curr = &mut head;
while let Some(node) = curr {
while let Some(node_next) = node.next.as_mut() {
if node_next.val == val {
node.next = node_next.next.take();
} else {
break;
}
}
curr = &mut node.next;
}
head
}
}
以上代码中,遇到的第一个疑问:
let mut head = head;
这里是rust的一个特性,变量遮蔽,将遮蔽之前的拥有所有权的head,好处是现在的head变量是可变的;
while let Some(node) = head.as_ref() {
if node.val == val {
head = head.unwrap().next
} else {
break;
}
}
这里node是一个head的引用,为什么还能head = head.unwrap().next,从生命周期角度来说,由于NLL,会找到最后一次使用node的位置,来标记它结束的位置,因此在node.val == val这个表达式这里结束了,和head这里修改和之前的引用不冲突。
let mut curr = &mut head;这里的含义非常丰富。
curr是一个可变的变量curr的类型是一个&Option<Box<ListNode>>curr所借用的head是可变的,改变它的内容的。
这里先默念curr是一个可变引用,
while let Some(node) = curr {
while let Some(node_next) = node.next.as_mut() {
if node_next.val == val {
node.next = node_next.next.take();
} else {
break;
}
}
curr = &mut node.next;
}
重点来了
while let Some(node) = curr这个表达了什么?
node是Some<Box
>中Box 的一个可变再借用。
这里隐式的发生了再借用。在使用再借用的变量时,不能使用被再借用的变量,否则会报错。先记住这个关键点。
while let Some(node_next) = node.next.as_mut()什么!!!又是对node再一次可变借用?到底是什么👻?
这里其实是对node的next字段进行了一个可变借用,这个规则是允许的。
等等。还有个问题。那就是next_node一份数据同时被node的next字段指向,以及next_node可变引用指向,这又问题了!next字段的是一个站上指向**Box<ListNode>**节点的指针,Box又指向了实际的值。
不是node的可变引用会导致他后边所有的节点的可变引用都被占有吗?
这里其实就是隐式的再借用,还是不能在再借用生命周期结束之前,对被借用的使用。
node.next = node_next.next.take(); 这不是在同一行么,不是冲突了吗?
其实这里右值先于左值结束,
curr = &mut node.next;这里生命周期不冲突了,curr在可变借用存在下,修嘎curr
这里先要明确curr是一个可变量。
- node 仍然存在,仍然借用 *curr 的旧值(head)
- curr 被重新赋值,指向新的位置(node.next)
- 这不是两个借用同时存在,而是 curr 改变了指向
作者: 咕咚!
出处: https://www.cnblogs.com/linga/
关于作者:专注虚拟化,运维开发,RPA,Rust,Go,Python!
本文版权归作者和博客园共有,禁止*.csdn.net转载,禁止以盈利为目的的转载,转载文章,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(oldsixa@163.com)咨询.

浙公网安备 33010602011771号