我在尝试用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:
改成这样就可以了, 具体的原因我也不是很清楚, 等大佬解答
改成这样就可以了, 具体的原因我也不是很清楚, 等大佬解答