154

エラーがわかりませんcannot move out of borrowed content。私は何度もそれを受け取り、常に解決してきましたが、理由がわかりませんでした。

例えば:

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の新しいバージョンでは、エラーは

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() {

次のような他の投稿を読んでも、エラーがわかりません。

この種のエラーの原因は何ですか?

4

1 に答える 1

135

の署名を見てみましょうinto_bytes:

fn into_bytes(self) -> Vec<u8>

これはself、self への参照 ( &self) ではなく、 を取ります。つまり、それはself消費れ、呼び出し後に利用できなくなります。その代わりに、Vec<u8>. プレフィックスinto_は、このようなメソッドを示す一般的な方法です。

あなたのメソッドが何を返すか正確にはわかりませんiter()が、私の推測では、それは に対するイテレータです&String。つまり、 a への参照を返しますがString、それらの所有権は与えません。つまり、値を消費するメソッドを呼び出すことはできません

あなたが見つけたように、1 つの解決策は を使用することcloneです。これにより、自分が所有していて呼び出すことができる複製オブジェクトが作成into_bytesされます。他のコメンターが言及しているように、 as_byteswhich takes を使用することもできる&selfため、借用した値で機能します。どちらを使用する必要があるかは、ポインターで行うことの最終目標によって異なります。

全体像では、これはすべて所有権の概念に関係しています。特定の操作はアイテムを所有することに依存し、他の操作はオブジェクトを借用することで回避できます (おそらくミュータブル)。参照 ( &foo) は所有権を付与するものではなく、単なる借用です。

関数の引数のself代わりに使用するのが興味深いのはなぜですか?&self

所有権の譲渡は、一般的に便利な概念です。私が何かを完了したときに、他の誰かがそれを所有している可能性があります。Rust では、これはより効率的な方法です。コピーを割り当てて、あなたにコピーを 1 つ渡してから、私のコピーを捨てるということを避けることができます。所有権は、最も寛大な状態でもあります。私がオブジェクトを所有している場合、私はそれを好きなように扱うことができます。


テスト用に作成したコードは次のとおりです。

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() {}
于 2015-01-26T21:51:37.160 に答える