2017-07-19 8 views
2

私は、ベクトルの上に数回反復したいと思います:イテレータを複製すると、基礎となるベクター全体がコピーされますか?

let my_vector = vec![1, 2, 3, 4, 5]; 
let mut out_vector = vec![]; 
for i in my_vector { 
    for j in my_vector { 
     out_vector.push(i * j + i + j); 
    } 
} 

J-ループは、エラー「移動後に、ここで使用される値を」持っています。私は&を2つのmy_vectorの前に置き、ベクトルを借りることができることを知っていますが、複数の方法で処理するのは良いことです。私は少しの洞察もしたいです。

代わりに、私は次のように書くことができます

let i_vec = vec![1, 2, 3, 4, 5, 6]; 
let iterator = i_vec.iter(); 
let mut out_vec = vec![]; 
for i in iterator.clone() { 
    for j in iterator.clone() { 
     out_vec.push(i * j + i + j); 
    } 
} 

私はWhat's the most efficient way to reuse an iterator in Rust?を見て:すべての彼らの「作品」はクローンことができれば

一般的にイテレータは、クローンができます。

実際のヒープ割り当てデータはイテレータの「ピース」ですか、それとも前述のヒープデータを指すメモリアドレスですか?

答えて

2

スライスイテレータ(これは、Vecまたは配列にiter()を呼び出すときに得られるイテレータのタイプです)は、基礎となるデータをコピーしません。どちらのイテレータも元のベクトルに格納されているデータを指しているので、クローン操作は安価です。

他のタイプのクローン可能イテレータでも同じことが起こりそうです。あなたのケースでは

は、代わりにi_vec.iter()を呼び出し、それをクローニングする、あなたはまた、i_vec.iter()を複数回呼び出すことができます。

for i in i_vec.iter() { 
    for j in i_vec.iter() { 

同じ結果を与えるが、おそらくより読みやすくしています。

+0

私は何かにi_vecをバインドしていないので、i_vec.iter()を2回使用するとborrow checkerの怒りに悩まされないと思います。 – Dragon

+0

@ドラゴンそれは、毎回読み取り専用の参照を取るので、それはうまく動作します。あなたの元のコードの問題は、for my_vector forは、ベクトルを消費します(それはベクトルからデータを移動するために使用されます)ので、その後はそのベクトルを使用できません。 – interjay

+1

さらにもっと慣用的な(Clippyが言うように) 'for i in&i_vec {for in&i_vec {...}}'です。 – Shepmaster

関連する問題