本文介绍了无法移出借用的内容/不能移出共享引用的后面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不理解错误cannot move out of borrowed content.我已经收到很多次了,而且我一直都解决了,但是我从来不明白为什么.

I don't understand the error cannot move out of borrowed content. I have received it many times and I have always solved it, but I've never understood why.

例如:

for line in self.xslg_file.iter() {
    self.buffer.clear();

    for current_char in line.into_bytes().iter() {
        self.buffer.push(*current_char as char);
    }

    println!("{}", line);
}

产生错误:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ cannot move out of borrowed content

在较新版本的Rust中,错误是

In newer versions of Rust, the error is

error[E0507]: cannot move out of `*line` which is behind a shared reference
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait

我通过克隆line解决了它:

for current_char in line.clone().into_bytes().iter() {

即使阅读过类似以下的文章,我也无法理解错误:

I don't understand the error even after reading other posts like:

  • Can't borrow File from &mut self (error msg: cannot move out of borrowed content)
  • Changing a node in a tree in Rust

这种错误的起因是什么?

What is the origin of this kind of error?

推荐答案

让我们看看 into_bytes :

Let's look at the signature for into_bytes:

fn into_bytes(self) -> Vec<u8>

这需要self,而不是对self(&self)的引用.这意味着self将被消耗 ,并且在通话后将不可用.取而代之的是Vec<u8>.前缀into_是表示此类方法的常用方式.

This takes self, not a reference to self (&self). That means that self will be consumed and won't be available after the call. In its place, you get a Vec<u8>. The prefix into_ is a common way of denoting methods like this.

我不完全知道您的iter()方法返回的内容,但是我猜想它是对&String的迭代器,也就是说,它返回对String的引用,但没有赋予您对它们的所有权.这意味着您无法调用使用该值的方法.

I don't know exactly what your iter() method returns, but my guess is that it's an iterator over &String, that is, it returns references to a String but doesn't give you ownership of them. That means you cannot call a method that consumes the value.

您已经发现,一种解决方案是使用clone.这将创建您拥有的重复对象,并且可以调用into_bytes.如其他评论者所述,您还可以使用 as_bytes ,它使用&self,因此它将在借入的值上工作.您应该使用哪一个取决于指针的最终目标.

As you've found, one solution is to use clone. This creates a duplicate object that you do own, and can call into_bytes on. As other commenters mention, you can also use as_bytes which takes &self, so it will work on a borrowed value. Which one you should use depends on your end goal for what you do with the pointer.

从更大的角度看,这全都与所有权的概念有关.某些操作依赖于拥有该物品,而其他操作则可以借用对象(也许是可变的)而逃脱.引用(&foo)不授予所有权,只是借用.

In the larger picture, this all has to do with the notion of ownership. Certain operations depend on owning the item, and other operations can get away with borrowing the object (perhaps mutably). A reference (&foo) does not grant ownership, it's just a borrow.

转让所有权通常是一个有用的概念-当我完成某件事时,其他人可能会拥有它.在Rust中,这是一种提高效率的方法.我可以避免分配副本,给您一个副本,然后扔掉我的副本.所有权也是最宽松的状态.如果我拥有一个对象,则可以根据需要使用它.

Transferring ownership is a useful concept in general - when I am done with something, someone else may have it. In Rust, it's a way to be more efficient. I can avoid allocating a copy, giving you one copy, then throwing away my copy. Ownership is also the most permissive state; if I own an object I can do with it as I wish.

这是我用来测试的代码:

Here's the code that I created to test with:

struct IteratorOfStringReference<'a>(&'a String);

impl<'a> Iterator for IteratorOfStringReference<'a> {
    type Item = &'a String;

    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

struct FileLikeThing {
    string: String,
}

impl FileLikeThing {
    fn iter(&self) -> IteratorOfStringReference {
        IteratorOfStringReference(&self.string)
    }
}

struct Dummy {
    xslg_file: FileLikeThing,
    buffer: String,
}

impl Dummy {
    fn dummy(&mut self) {
        for line in self.xslg_file.iter() {
            self.buffer.clear();

            for current_char in line.into_bytes().iter() {
                self.buffer.push(*current_char as char);
            }

            println!("{}", line);
        }
    }
}

fn main() {}

这篇关于无法移出借用的内容/不能移出共享引用的后面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 06:19