我正在尝试做Simple Linked List运动问题,但是我坚持执行pop()
方法。我得到的错误对我来说不是很清楚。我想我不太习惯Rust的思维方式。
此外,由于编译器的建议,我添加了一堆我不太了解的as_ref()
。
我很想知道为什么我的工作方式比解决方案更有用。
pub struct SimpleLinkedList<T> {
head: Option<Box<Node<T>>>,
}
struct Node<T> {
data: T,
next: Option<Box<Node<T>>>,
}
impl<T> SimpleLinkedList<T> {
pub fn new() -> Self {
unimplemented!()
}
pub fn len(&self) -> usize {
unimplemented!()
}
pub fn push(&mut self, _element: T) {
unimplemented!()
}
pub fn pop(&mut self) -> Option<T> {
// Recursive function to return the before last element of the list
fn get_before_last<'a, T>(
prev: &'a Box<Node<T>>,
current: &'a Box<Node<T>>,
) -> &'a Box<Node<T>> {
match ¤t.next {
Some(next_node) => get_before_last(¤t, &next_node),
None => &prev,
}
}
// Check if the head is None
match &self.head {
None => return None,
_ => (),
};
let before_last = &mut match &self.head {
// Beginning of the recursion
Some(node) => get_before_last(&node, node.next.as_ref().unwrap()),
None => self.head.as_ref().unwrap(),
};
let to_pop = before_last.next.as_ref();
before_last.next = None;
Some(to_pop.unwrap().data)
}
}
我收到以下错误:
error[E0594]: cannot assign to `before_last.next` which is behind a `&` reference
--> src/lib.rs:48:9
|
48 | before_last.next = None;
| ^^^^^^^^^^^^^^^^ cannot assign
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:50:14
|
50 | Some(to_pop.unwrap().data)
| ^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
答案 0 :(得分:1)
在您的代码中,before_last
是不可变的。实际上,它是&mut &'a Box<Node>
。因此,您无法为节点分配任何内容,因为它是对不可变节点的可变引用。
我能给您的最好建议是重新考虑实现。您可以在前面进行操作,而不是将其弹出并拖到链的末端。 创建一个新的装箱节点,删除头部并将其放在新节点的下一个字段中。然后新节点成为头。
这样,您就拥有了LIFO列表,而不必遍历整个列表即可进行推送和弹出,因此它也更加有效。推到最前面还可以减少所需的代码量。
我的解决方法是available on Exercism。