不能移出借来的内容/不能移出共享参考的后面 [英] Cannot move out of borrowed content / cannot move out of behind a shared reference

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

问题描述

我不明白错误不能移出借来的内容.收到很多次了,一直都解决了,但一直不明白为什么.

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解决了这个问题:

I solved it by cloning line:

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

即使在阅读其他帖子后我也不明白错误:

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

这种错误的根源是什么?

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.前缀 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.

为什么在函数的参数中使用 self 而不是 &self 很有趣?

Why is it interesting to use self instead of &self in a function's arguments?

转让所有权通常是一个有用的概念 - 当我完成某件事时,其他人可能会拥有它.在 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() {}

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

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