2016-08-05 3 views
5

の外に移動することはできません:私は、次を得るしかしは、構造体の中にVecとを反復 - 私は<code>Vec</code>を反復処理しようとし<code>Vec</code>が含まれている構造体の機能を書いています借りコンテンツ

struct Object { 
    pub v: Vec<f32>, 
} 

impl Object { 
    pub fn sum(&self) -> f32 { 
     let mut sum = 0.0; 
     for e in self.v { 
      sum += e 
     } 
     sum 
    } 
} 

をエラー:

error: cannot move out of borrowed content [E0507] 
     for e in self.v { 
       ^~~~ 
help: run `rustc --explain E0507` to see a detailed explanation 

私の理解では、self以来借りていることにあるループ反復のためevアウトの要素を移動しようとしていること?

エラーコードから、潜在的な解決策は所有権を取得することだと私は読んだが、私はそれをどうやって行うかについてはあまり確信していない。

私はベクトルまたはその要素を変更しようとしていません。私はちょうどいくつかの計算を実行するために要素を使いたいです。

+0

同じエラーメッセージで** [他の質問は**]を見ましたか?(http://stackoverflow.com/search?q=%5Brust%5D+cannot+move + out + of + borrowed + content +は%3Aqです)? – Shepmaster

答えて

13

行:for e in self.vは本質的にはfor e in (*self).vです。移動によってベクトル上を反復しようとしていて、そのIntoIterの特性を呼び出しています。これはベクトルを完全に破壊し、すべての数値を永遠に移動させます。これはあなたが望むものではないだけでなく、この文脈では許可されていないため、読めないためです。

実際には、参照によって繰り返し処理します。これを行うには2つの方法があります。

for e in &self.v { 
    //... 
} 

これは本質的に、あなたが実際にはベクトルを借りたいコンパイラに指示する必要があり.自動逆参照するので、&((*self).v)を言っています。

または

for e in self.v.iter() { 

} 

iter&selfを取るので、これは面白いに見えることがあります。どうして?まあ、参照を取る値で関数を呼び出すと、コンパイラーは自動参照も行います。これは本質的には(&((*self).v)).iter()ですが、コンパイラが助けてくれるように書くのは辛口でしょう。

なぜ、forループで自動参照しないのですか?まあ、for x in self.vは有効な文であり、あなたが書こうと思ったものかもしれません。コンパイラが、あなたが望むものは他のものを必要としていると仮定することよりも不可能であることを伝えることが、より重要です。上のauto(de-)参照では、あいまいさはありません。

イテレーターアダプターを使用する場合は前者の方が適していますが、後者の方が必要です。

と言えば、あなたのsumはすでに夜間に存在します。ちょうどself.v.iter().sum()と書いてください。そうでなければ、あなたは使用することができますself.v.iter().fold(0.0, |(acc, &v)| acc + v)

+0

素晴らしいです、それは完全に動作します。本当にありがとう。これは、 'self.struct_member'を呼び出すたびにrustコンパイラが'(* self).struct_member'と見て、構造体から移​​動することを意味しますか?あるいは、 'for x in self.v'構造体に特有です。 – illeyezur

+0

@illeyezurこれは常に起こります(' Copy'型を除いて、それは 'Copy'型が一般に動かないためです)。 – LinearZoetrope

関連する問題