イテレータについて整理
for式を書くと所有権まわりのエラーが出てしまい、よくわからなかったので整理する。
into_iter()
let numbers = vec![1, 2, 3];
for number in numbers {
// numberは要素そのもの
}
// numbersは再利用不可
公式ドキュメントにある通り、for式はコレクションに対してIntoIteratorトレイトのinto_iter()を呼びIteratorトレイトを実装するものを生成する。そして、それに対しnext()を呼ぶことで要素を取り出す。
fn into_iter(self) -> Self::IntoIter
定義によるとinto_iter()はselfを受けるため、Copyトレイトが実装されていなければmoveが発生する。なので、for式のあとで再利用しようとしてエラーが発生してしまう。
iter(), iter_mut()
let numbers = vec![1, 2, 3];
for number = numbers.iter() {
// numberは要素への参照
}
// numbersは再利用可
ここからの話はVec型を想定する。moveを発生させたくない場合、iter()やiter_mut()を使う。
pub fn iter(&self) -> Iter<T>
into_iter()とは違い、&selfを受けるのでmoveは発生しない。Vec型の実装だと、std::slice::Iter型を返す。なので、for式はこのIter型のinto_iter()を呼ぶことになるが、実装を見るとselfを返しているだけ。Iter型はIteratorトレイトも実装しているということになる。
let numbers = vec![1];
let mut iterator = numbers.iter();
assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), None);
Iter型のnext()の実装を見てみたけど、現時点では理解できそうになかった。ただ、上のコードの通り、next()は要素の不変の参照を返す。一方で、iter_mut()ではこれが可変の参照になる。