尝试转让所有权时无法移出借用内容 [英] Cannot move out of borrowed content when trying to transfer ownership

查看:27
本文介绍了尝试转让所有权时无法移出借用内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个链表来围绕 Rust 的生命周期、所有权和引用.我有以下代码:

I'm writing a linked list to wrap my head around Rust lifetimes, ownership and references. I have the following code:

pub struct LinkedList {
    head: Option<Box<LinkedListNode>>,
}

pub struct LinkedListNode {
    next: Option<Box<LinkedListNode>>,
}

impl LinkedList {
    pub fn new() -> LinkedList {
        LinkedList { head: None }
    }

    pub fn prepend_value(&mut self) {
        let mut new_node = LinkedListNode { next: None };

        match self.head {
            Some(ref head) => new_node.next = Some(*head),
            None => new_node.next = None,
        };

        self.head = Some(Box::new(new_node));
    }
}

fn main() {}

但我收到以下编译错误:

But I am getting the following compilation error:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:18:52
   |
18 |             Some(ref head) => new_node.next = Some(*head),
   |                                                    ^^^^^ cannot move out of borrowed content

较新版本的 Rust 有一个稍微不同的错误:

Newer versions of Rust have a slightly different error:

error[E0507]: cannot move out of `*head` which is behind a shared reference
  --> src/main.rs:18:52
   |
18 |             Some(ref head) => new_node.next = Some(*head),
   |                                                    ^^^^^ move occurs because `*head` has type `std::boxed::Box<LinkedListNode>`, which does not implement the `Copy` trait

我认为 head 节点当前必须由 self 拥有,也就是链表.当我将它分配给 new_node.next 时,可能会发生所有权变更.

I'm thinking that the head node must currently be owned by self, which is the linked list. When I assign it to new_node.next, there is probably a change of ownership that will happen.

如果可能,我宁愿不克隆该值,因为这看起来很浪费.我不想在函数的持续时间内借用"它.我真的很想转让它的所有权.

I would rather not clone the value if possible as that seems wasteful. I don't want to just "borrow" it for the duration of the function. I really want to transfer its ownership.

我该怎么做?

我已经看过搬不出来在 &mut self 方法中解包成员变量时借用的内容不能移出借来的内容/无法移出共享参考的后面.

我尝试按照其中一个问题的已接受答案中的建议移除匹配臂,并在创建新的 LinkedListNode 时定义 next,但我得到了相同的结果错误信息.

I tried removing the match arm as suggested in the accepted answer in one of those questions and defining next in the creation of the new LinkedListNode, but I get the same error message.

我已经成功添加了一个 append 方法,该方法将 LinkedListNode 添加到列表的末尾.

I have successfully added an append method which takes a LinkedListNode to add to the end of the list.

推荐答案

尝试转让所有权时无法移出借用的内容

Cannot move out of borrowed content when trying to transfer ownership

在高层次上,这对 Rust 来说是不合时宜的.你不能转让借来的东西的所有权因为你不拥有它.你不应该借我的车(&Car)然后把它给你在街上看到的第一个人!即使我把我的车借给你并允许你对其进行更改,这仍然是正确的(&mut Car).

At a high-level, this is against-the-grain for Rust. You cannot transfer ownership of something borrowed because you don't own it. You shouldn't borrow my car (&Car) and then give it to the first person you see on the street! This is still true even if I lend you my car and allow you to make changes to it (&mut Car).

您根本无法将 head 移出 &self,因为您无法改变该值.

You cannot move head out of a &self at all because you cannot mutate the value.

您不能将 head&mut self 中移出,因为这会使 LinkedList 结构处于不一致状态 - 其中之一字段将具有未定义的值.这是 Rust 安全保证的核心措施.

You cannot move head out of a &mut self because this would leave the LinkedList struct in an inconsistent state - one of the fields would have an undefined value. This is a core measure of Rust's safety guarantees.

一般来说,您需要遵循 如何为可变引用中的字段交换新值结构?替换现有值.

In general, you will need to follow something from How can I swap in a new value for a field in a mutable reference to a structure? to replace the existing value.

在这种情况下,您可以使用 选项::采取.这会将变量留在原处,将其就地更改为 None 并返回先前的值.然后您可以使用该值来构建列表的新头部:

In this case, you can use Option::take. This will leave the variable where it is, changing it in-place to a None and returning the previous value. You can then use that value to build the new head of the list:

pub fn prepend_value(&mut self) {
    let head = self.head.take();
    self.head = Some(Box::new(LinkedListNode { next: head }));
}

更通用的解决方案是获取结构的所有权而不是借用它.这使您可以为所欲为.请注意,我们采用 self 按值,而不是按引用:

A more generic solution is to take ownership of the struct instead of borrowing it. This allows you to do whatever you want to it. Note that we take self by-value, not by-reference:

pub fn prepend_value(mut self) -> LinkedList {
    self.head = Some(Box::new(LinkedListNode { next: self.head }));
    self
} 

这篇关于尝试转让所有权时无法移出借用内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆