0Pricing
Lua Academy · レッスン

クロージャによるステートフルイテレーター

クロージャで呼び出し間の状態を保持するイテレーターを作成します。

「クロージャによるステートフルイテレーター」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ジェネリックforプロトコル
  2. ステートレスイテレーター
  3. クロージャによるステートフルイテレーター
  4. コルーチンベースのジェネレーター
← Lua Academyに戻る