クロージャによるステートフルイテレーター
クロージャで呼び出し間の状態を保持するイテレーターを作成します。
「クロージャによるステートフルイテレーター」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
クロージャが役立つ場面
イテレーターが複雑で変化する状態(位置、スタック、履歴など)を保持する必要がある場合、クロージャが自然な選択肢です。状態はUpvalueに保持されます。
クロージャイテレーターのパターン
1つの関数だけを返し、状態はUpvalueに保持します。Generic forは外部のstateを受け取らず、毎回その関数を呼び出すだけです。
local function chars(s)
local i = 0
return function()
i = i + 1
local c = s:sub(i, i)
return c ~= "" and c or nil
end
end
for c in chars("lua") do print(c) endファイル行イテレーター
古典的な状態を持つクロージャーイテレーターは、EOF に達するまでファイルハンドルから行を返します。
local function lines(filename)
local f = io.open(filename, "r")
return function()
local line = f:read("*l")
if not line then f:close() end
return line
end
endフィルタリングイテレーター
既存のイテレーターを、述語に一致しない要素をスキップするクロージャーでラップします。
local function filtered(iter, pred)
return function()
local v = iter()
while v ~= nil and not pred(v) do
v = iter()
end
return v
end
endマッピングイテレーター
マッピングイテレーターは、中間テーブルを作成せずに各要素をその場で変換します。
local function mapped(iter, fn)
return function()
local v = iter()
if v ~= nil then return fn(v) end
end
end結合イテレーター
zip イテレーターは2つのイテレーターから同時に値を取得し、どちらか一方が使い果たされた時点で停止します。
local function zipped(iter1, iter2)
return function()
local a, b = iter1(), iter2()
if a ~= nil and b ~= nil then return a, b end
end
end連結イテレーター
chain イテレーターは、次のイテレーターに切り替える前に、現在のイテレーターを最後まで処理します。
local function chained(...)
local iters = {...}
local idx = 1
return function()
while idx <= #iters do
local v = iters[idx]()
if v ~= nil then return v end
idx = idx + 1
end
end
endカウント付きイテレーター
クロージャーのカウンターを使って、イテレーターが返す値を最大 N 個に制限します。
local function take(n, iter)
local count = 0
return function()
count = count + 1
if count <= n then return iter() end
end
endツリー走査イテレーター
深さ優先のツリー走査では、スタック(upvalue としてのテーブル)を使って走査状態を保持します。
local function dfs(root)
local stack = {root}
return function()
if #stack == 0 then return nil end
local node = table.remove(stack)
for _, child in ipairs(node.children or {}) do
stack[#stack+1] = child
end
return node
end
endメモリに関する考慮事項
状態を持つイテレーターはクロージャーオブジェクトを割り当てます。非常に処理密度の高い内側のループでは、状態を持たないイテレーターのほうが適している場合があります。複雑な走査では、クロージャーを使う価値が十分にあります。
比較:状態ありと状態なし
- 状態あり:複雑な状態を扱え、任意の走査順序に対応し、記述も簡単です。
- 状態なし:単純な順次アクセス向けで、割り当てがなく高速です。
状態を持つイテレーターに関する質問
状態を持つクロージャーイテレーターは、どこに状態を保存しますか?
復習:状態を持つイテレーター
クロージャーベースの状態を持つイテレーターは、複雑な走査状態を upvalue に保存します。これにより、フィルター、マップ、ツリー、遅延パイプラインを、すべて組み合わせ可能かつメモリ効率よく実現できます。
よくある質問
「クロージャによるステートフルイテレーター」レッスンは無料ですか?
はい。「クロージャによるステートフルイテレーター」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「クロージャによるステートフルイテレーター」で何を学びますか?
クロージャで呼び出し間の状態を保持するイテレーターを作成します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「クロージャによるステートフルイテレーター」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ジェネリックforプロトコル
- ステートレスイテレーター
- クロージャによるステートフルイテレーター
- コルーチンベースのジェネレーター