Rust 所有权问题

问题描述 投票:0回答:1

我想用 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 {
rust borrow-checker ownership
1个回答
0
投票

你知道无论如何你都会替换

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);
}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.