0Pricing
Lua Academy · Урок

Итераторы с состоянием и замыканиями

Создавайте итераторы, сохраняющие состояние между вызовами с помощью замыканий.

«Итераторы с состоянием и замыканиями» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Когда полезны замыкания

Если итератору нужно хранить сложное изменяющееся состояние (позицию, стек, историю), замыкания становятся естественным инструментом. Состояние хранится во внешних переменных.

Шаблон итератора-замыкания

Возвращайте одну функцию, а состояние храните во внешних переменных. Обобщённый for не предоставляет внешнего состояния, а просто вызывает функцию при каждой итерации.

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

Объединённый итератор

Итератор объединения одновременно получает значения из двух итераторов и останавливается, когда один из них исчерпан.

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

Цепочечный итератор

Цепочечный итератор исчерпывает один итератор, прежде чем перейти к следующему.

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

Итератор обхода дерева

Обход дерева в глубину использует стек (таблицу в качестве замыкания) для хранения состояния обхода.

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

Особенности использования памяти

Итераторы с состоянием выделяют объект замыкания. Для чрезвычайно плотных внутренних циклов может оказаться предпочтительнее итератор без состояния. Для сложных обходов замыкание полностью оправдывает себя.

Сравнение: с состоянием и без состояния

  • С состоянием: сложное состояние, любой порядок обхода, простота написания.
  • Без состояния: простой последовательный доступ, отсутствие выделения памяти, высокая скорость.

Вопрос об итераторе с состоянием

Где итератор-замыкание с состоянием хранит своё состояние?

Итоги: итераторы с состоянием

Итераторы с состоянием на основе замыканий хранят сложное состояние обхода в переменных верхнего уровня, что позволяет создавать фильтры, отображения, обходы деревьев и ленивые конвейеры — всё это можно комбинировать с эффективным использованием памяти.

Часто задаваемые вопросы

Урок «Итераторы с состоянием и замыканиями» бесплатный?

Да — полный текст урока «Итераторы с состоянием и замыканиями» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Итераторы с состоянием и замыканиями»?

Создавайте итераторы, сохраняющие состояние между вызовами с помощью замыканий. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Итераторы с состоянием и замыканиями»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Протокол обобщённого for
  2. Итераторы без состояния
  3. Итераторы с состоянием и замыканиями
  4. Генераторы на основе сопрограмм
← Назад к Lua Academy