我想用 Rust 实现单链表概念。 但是,当我实现push_front函数时出现问题。
错误信息如下。 无法移出
self.head
作为枚举变体 Some
,它位于可变引用后面
如何解决这个问题?
//! Singly linked list.
//!
//! Consult <https://doc.rust-lang.org/book/ch15-01-box.html>.
use std::fmt::Debug;
/// Node of the list.
#[derive(Debug)]
pub struct Node<T: Debug> {
/// Value of current node.
pub value: T,
/// Pointer to the next node. If it is `None`, there is no next node.
pub next: Option<Box<Node<T>>>,
}
impl<T: Debug> Node<T> {
/// Creates a new node.
pub fn new(value: T) -> Self {
Self { value, next: None }
}
}
/// A singly-linked list.
#[derive(Debug)]
pub struct SinglyLinkedList<T: Debug> {
/// Head node of the list. If it is `None`, the list is empty.
head: Option<Node<T>>,
}
impl<T: Debug> Default for SinglyLinkedList<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Debug> SinglyLinkedList<T> {
/// Creates a new list.
pub fn new() -> Self {
Self { head: None }
}
/// Adds the given node to the front of the list.
pub fn push_front(&mut self, value: T) {
let mut new_node = Node::new(value);
new_node.next = match self.head {
Some(head_node) => Some(Box::new(head_node)),
None => None
};
self.head = Some(new_node);
}
}
error: cannot move out of `self.head` as enum variant `Some` which is behind a mutable reference
--> src/lib.rs:46:31
|
46 | new_node.next = match self.head {
| ^^^^^^^^^
47 | Some(head_node) => Some(Box::new(head_node)),
| ---------
| |
| data moved here
| move occurs because `head_node` has type `Node<T>`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
46 | new_node.next = match &self.head {
你知道无论如何你都会替换
self.head
所以我们现在就可以移出它,但编译器不知道这一点。您可以使用 take()
: 来帮助编译器
/// Adds the given node to the front of the list.
pub fn push_front(&mut self, value: T) {
let mut new_node = Node::new(value);
new_node.next = match self.head.take() {
Some(head_node) => Some(Box::new(head_node)),
None => None,
};
self.head = Some(new_node);
}
match
也可以使用map()
来缩短:
/// Adds the given node to the front of the list.
pub fn push_front(&mut self, value: T) {
let mut new_node = Node::new(value);
new_node.next = self.head.take().map(Box::new);
self.head = Some(new_node);
}
游乐场。