後に使用されるオブジェクトは、汎用ループin
によって繰り返し呼び出される関数でなければなりません。for
テーブルまたはユーザー オブジェクトを関数のように呼び出し可能にすることができるかどうかはわかりませんが、それでも問題は、オブジェクトが 1 つの内部反復子状態しか持てないことです。つまり、同じオブジェクトに対して複数の反復を許可しません (どちらも何らかの方法で明示的にリセットしない限り。
Stuart が答えたように、メタメソッドを__call
適切に使用してイテレータを返すことができますが、その場合は次のように記述する必要があります。
for obj in myObject() do
obj:foo()
end
これは私たちが望んでいるものではありません。
PiLをもう少し読むと、 for ループで使用されるコンポーネントが他にもあることがわかります。不変ループの状態と、各呼び出しでイテレータ関数に渡される制御変数の現在の値です。式でそれらを提供しない場合in
、それらは に初期化されnil
ます。
したがって、私の考えは、これらの値を使用して個々の呼び出しを区別することです。
next(element)
各要素に対して次の要素を返すコレクションの関数を作成できる場合、実装は簡単になります。
metatable.__call = function(_state, _last)
if(_last == nil) then
return obj:first()
else
return obj:next(_last)
end
end
しかし、多くの場合、このようなものはなく、より複雑になります。
ここでコルーチンを使用することを考えましたが、これらにはまだファクトリ メソッドが必要です (これは避けたい)。これは、Stuart が書いたものと似たような結果になり (つまり、イテレータの状態をオブジェクト自体のどこかに保存するか、オブジェクトに関連する他の変数に保存します)、パラメータおよび/またはイテレータの結果を使用して、いつオブジェクトを作成/消去するかを決定します。イテレータ オブジェクト/状態。
ここでは何も勝ちませんでした。