我在尝试用Rust实现一个单链表,在实现向尾部插入元素的时候rust报了错误,错误说发生了两次可变借用。可是第一个可变借用应该在第二次可变借用后就到期了啊。不太能理解错误的原因,请指教。部分源码如下
type Link<T> = Option<Box<Node<T>>>;
#[derive(Debug)]
pub struct LinkList<T> {
head: Link<T>,
}
#[derive(Debug)]
struct Node<T> {
ele: T,
next: Link<T>,
}
impl<T> LinkList<T> {
...
pub fn push_back(&mut self, ele :T) {
let new_node = Node {
ele: ele,
next: None
};
match self.head.as_mut() {
None => {self.head = Link::Some(Box::new(new_node))}
Some(mut ptr) => {
while let Some(next_link) = &mut ptr.next{ //first
ptr = next_link;
}
ptr.next.replace(Box::new(new_node)); // second
}
}
}
}
错误提示
error[E0499]: cannot borrow `ptr.next` as mutable more than once at a time
--> src/linklist.rs:31:17
|
28 | while let Some(next_link) = &mut ptr.next{
| ------------- first mutable borrow occurs here
...
31 | ptr.next.replace(Box::new(new_node));
| ^^^^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
error: aborting due to previous error
1
共 5 条评论, 1 页
评论区
写评论感谢各位大大。
Option
实现Copy
是有限制的:所以能通过的原因绝对不是因为这个,因为在本例中,
Node<T>
没有实现Copy
,所以,此时的Option<Node<T>>
自然也没有实现Copy
。 这里能有效的原因其实是使用了ref
,正常情况下的模式匹配,属于消耗匹配的值,也就是说匹配的过程当中发生了move
,而使用了ref
能够指明在匹配的时候不move
仅仅借用。 关于ref
的具体文档,请看这里:https://doc.rust-lang.org/stable/std/keyword.ref.html--
👇
zhylmzr: 大概能理解这样写能通过的原因了. 因为
Option
实现了Copy
, 所以这一行是copy move
到ptr
了, 自然不存在一个值多次的可变借用.原本的写法,
ptr.next
被可变借用到了next_link
,next_link
又被move到ptr
, 那么ptr.next
的可变借用生命周期和ptr
相同. 而ptr
就是作为可变借用定义的, 所以在while之后访问ptr
就会出现二次可变借用了.--
👇
zhylmzr:
改成这样就可以了, 具体的原因我也不是很清楚, 等大佬解答
大概能理解这样写能通过的原因了. 因为
Option
实现了Copy
, 所以这一行是copy move
到ptr
了, 自然不存在一个值多次的可变借用.原本的写法,
ptr.next
被可变借用到了next_link
,next_link
又被move到ptr
, 那么ptr.next
的可变借用生命周期和ptr
相同. 而ptr
就是作为可变借用定义的, 所以在while之后访问ptr
就会出现二次可变借用了.--
👇
zhylmzr:
改成这样就可以了, 具体的原因我也不是很清楚, 等大佬解答
改成这样就可以了, 具体的原因我也不是很清楚, 等大佬解答