TL;DR

コレクションなどの次の要素を、要素がなくなるまで 1 つずつ順に返すオブジェクトである。for-each ループと組み合わせて、ループを抽象化するのに使う。

なぜ必要か

Effective Rust によると、最近のプログラミング言語は、イテレータと for-each ループでループを抽象化している。for-each はコンテナのすべての要素について繰り返し実行するループで、ループ変数は要素そのものになる。

仕組み

Rust では、Iterator トレイトの next メソッドがイテレータの中心である。next は要素があるあいだ Some(Item) を返し、要素がなくなると None を返して繰り返しの終わりを知らせる。

trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

コレクションからイテレータを作る方法は、&T を返す iter()、&mut T を返す iter_mut()、T を返す into_iter() の 3 つが一般的である。for ループは、IntoIterator トレイトを使ってイテレータに変換する糖衣構文である。

map、filter、take のように、イテレータを受け取って別のイテレータを返す関数をイテレータアダプタと呼ぶ。

例

Effective Rust の例では、iter() を起点にイテレータ変換をつなげて合計を求めている。

collection.iter().map(|thing| thing.0).sum()

注意点

Rust のイテレータとイテレータアダプタは遅延評価で、作っただけでは何も起きない。next を呼んで初めて処理が進む。また、into_iter で要素を消費すると、元のコレクションは再利用できない。

関連

出典