我最近一直在尝试自学一些 Rust,并想通过实现一个简单的链表来练习一下。我从 Rust 库的链表中获得了一些灵感,并尝试复制我已经理解的部分。我还决定暂时将其设为单链接。
struct Node<T> {
element: T,
next: Option<Box<Node<T>>>,
}
impl<T> Node<T> {
fn new(element: T) -> Self {
Node {
element: element,
next: None,
}
}
fn append(&mut self, element: Box<Node<T>>) {
self.next = Some(element);
}
}
pub struct LinkedList<T> {
head: Option<Box<Node<T>>>,
tail: Option<Box<Node<T>>>,
len: u32,
}
impl<T> LinkedList<T> {
pub fn new() -> Self {
head: None,
tail: None,
len: 0,
}
pub fn push(&mut self, element: T) {
let node: Box<Node<T>> = Box::new(Node::new(element));
match self.tail {
None => self.head = Some(node),
Some(mut ref tail) => tail.append(node),
}
self.tail = Some(node);
self.len += 1;
}
pub fn pop(&mut self) -> Option<T> {
//not implemented
}
pub fn get(&self, index: u32) -> Option<T> {
//not implemented
}
}
这就是我目前所得到的;据我了解,此代码的问题在于 Box
不能有多个引用以保持内存安全。
所以当我将列表头设置为节点时
None => self.head = Some(node),
我不能继续设置
self.tail = Some(node);
稍后,我的理解是否正确?这样做的正确方法是什么?我是否必须像在库中那样使用 Shared
,或者是否可以使用 Box
或其他一些类型?
最佳答案
您的问题是您在移动一个值 ( node
) 后尝试使用它;自 Box<Node<T>>
不执行 Copy
, 当你在 match
中使用它时表达式:
match self.tail {
None => self.head = Some(node),
Some(ref mut tail) => tail.append(node),
}
node
移动到 self.head
或 self.tail
并且以后不能再使用了。除了必读 Learning Rust With Entirely Too Many Linked Lists要了解您可以在 Rust 中实现链表的不同方式,我建议您首先在 Rust 的基本概念领域进行更多研究,尤其是:
关于linked-list - Rust 中的单链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41653148/