Code Fix

中級

for ループで Vec を直接回すと要素がムーブされる

for x in vec のように所有権を持つVecを直接forに渡すと、内部でinto_iter()が呼ばれ各要素の所有権がムーブされます。ループの後で元のVecを使おうとするとE0382エラーになります。

エラーメッセージの読み方

error[E0382]: borrow of moved value: `names`
E0382
エラーコード — `rustc --explain E0382` で詳しい説明が見られます
borrow of moved value: `names`
詳細メッセージ — 何が問題だったか

このエラーが出る典型パターン

パターン1

 1  fn main() {
 2      let names = vec![String::from("a"), String::from("b")];
 3      for name in names         {
                          ^
 4          println!("{}", name);
 5      }
 6      println!("{}", names.len());
 7  }
error[E0382]: borrow of moved value: `names`

forに所有権を持つVecを直接渡すと要素がムーブされます。ループ後も使いたい場合は&で参照を渡します。

直し方: names&names にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  fn main() {
 2      let words = vec![String::from("x"), String::from("y")];
 3      for w in words          {
                        ^
 4          println!("{}", w);
 5      }
 6      println!("{}", words.len());
 7  }
error[E0382]: borrow of moved value: `words`

所有権ごと消費するforループの後で元のVecを参照すると、E0382エラーになります。

直し方: words&words にします。

この問題を解いてみる →

パターン3

 1  fn main() {
 2      let items = vec![String::from("p"), String::from("q")];
 3      for it in items         {
                        ^
 4          println!("{}", it);
 5      }
 6      println!("{}", items.len());
 7  }
error[E0382]: borrow of moved value: `items`

&を付けて渡せば、要素を借用するだけでitemsの所有権は失われません。

直し方: items&items にします。

この問題を解いてみる →

パターン4

 1  fn main() {
 2      let labels = vec![String::from("m"), String::from("n")];
 3      for l in labels         {
                        ^
 4          println!("{}", l);
 5      }
 6      println!("{}", labels.len());
 7  }
error[E0382]: borrow of moved value: `labels`

参照付きのforは要素を&Stringとして借用するだけなので、ループの後もlabels自体は生きています。

直し方: labels&labels にします。

この問題を解いてみる →

パターン5

 1  fn main() {
 2      let tags = vec![String::from("s"), String::from("t")];
 3      for t in tags          {
                       ^
 4          println!("{}", t);
 5      }
 6      println!("{}", tags.len());
 7  }
error[E0382]: borrow of moved value: `tags`

要素を消費する必要が無いなら、常に&を付けて借用でループする方が安全です。

直し方: tags&tags にします。

この問題を解いてみる →

よくある誤解

「forループは要素を一時的に借りるだけで、元のコレクションは手つかずのまま残るはず」という思い込みは誤りです。&を付けずにforに渡すと所有権ごと消費されるため、ループ後に使いたい場合は&vecのように参照で渡す必要があります。

まとめ

for ループで Vec を直接回すと要素がムーブされるは中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)