#はじめに
以下では、「イテレータが何者か理解したい」という方へ、そのイメージを伝えることを優先しており、実際の動きとは多少異なります。 正しい動きについては、各種リファレンスをお読みください。
また、.Net(VB/C#)では「イテレータ(Iterator)/反復子」ではなく「イニュマレータ(Enumerator)/列挙子」と呼んでいます。
#イテレータ…?
私は、.NET(VB/C#)とJavaしか知らないのですが、どの言語にもイテレータまたはそれに類するものが存在すると思います。 これについて、私が理解(らしきことを)した時のことをまとめてみます。
##ネットで情報を漁る
ネットでいろいろな方が、イテレータについて具体的な例を挙げ分かりやすいように説明しています。 しかし私は「それがどんな感じか?」を先に(それも比喩で)掴んでいないと、理解が進まない人でした。 そこで、こんな風に理解しました。
##わんこ蕎麦とイテレータ
わんこ蕎麦は、お盆の上に少量の蕎麦がもられたお椀が載っており、給仕する方が一つずつ、食べる人の前にあるお椀によそうことを繰り返します。 ここでの登場人物が、それぞれ
- お盆 : コレクション
- お椀 : 要素(アイテム/エレメント)
- よそう人 : イテレータ
- 食べる人 : 要素を受け取る処理
に対応づけることができます。
少しだけ普通と違うのは、食べる人が**「次ある?じゃぁ寄越して!」と要求して、よそってくれるというところでしょうか。 ちなみに、お椀が無くなると、よそう人は「もうありません!」と答えてくれます。
##よそう人がいなかったら
よそってくれる人がいなかったら、自分でよそうしかありません。 しかし、地方(コレクションの種類)によってはお盆に乗っているのではなく棚に入っていたり、お椀の並び順が謎だったりするので、食べる人がいちいちそれを覚えておかなければなりません。
一般的にオブジェクト指向では「細かい事は、それ(コレクション)自身が知っていればいい。使用者は命令するだけ」とすることが推奨されます。
そのため、どんなもの(各種コレクション)でも「よそう人」を用意しておくことで、食べること(処理すること)に集中させましょう、ということを目指し出来たものがイテレータさんです。
##イテレータさんがいることの保証
Javaでは「Iterable」、.NETでは「IEnumerable」インタフェースを実装しているオブジェクトに「イテレータ召喚!(Iterator or GetEnumerator)」と唱えると、イテレータさんが「どーもどーも」と出てきます。
##かくして拡張for文が使える
拡張for文、Foreachは、コレクションからイテレータさんを召喚してグルグルと処理を回しています。言い方を変えると「拡張for文にかけられるのはIterable or IEnumerableを実装したクラスだけ」とも言えます。
##コレクションとイテレータさんは別のオブジェクト
なんとなく、コレクションとイテレータさんは「傍にいる」イメージをいだきませんか? こう、常に寄り添って、コレクションからポンポン要素を放り投げてくるみたいな。
しかし、別のオブジェクトなので「イテレータさんを引っ張り出して、他へ回す」**こともできます。 あまり褒められた使い方ではありませんが、遠くのオブジェクトにイテレータさんだけを渡し、そこで「次!次!」と要求することもできます。
##おわりに
イテレータって何ですか?と質問された時に、イメージを伝える時の参考になれば幸いです。