Обобщённый for и break
Используйте обобщённый for с pairs/ipairs и управляйте ходом цикла с помощью break.
«Обобщённый for и break» — бесплатный урок Lua Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Протокол обобщённого цикла for
Обобщённый цикл for в Lua работает с функцией-итератором. Синтаксис имеет вид for vars in iter_func, state, init do. На каждой итерации Lua вызывает iter_func(state, lastVar) и присваивает возвращённые значения переменным vars. Цикл останавливается, когда первое возвращённое значение равно nil.
-- Manual use of next() iterator
local t = {a=1, b=2, c=3}
local key, val = next(t, nil) -- first entry
while key ~= nil do
print(key, val)
key, val = next(t, key) -- advance
endpairs() для всех ключей
pairs(t) возвращает итератор, который перебирает все пары «ключ-значение» в таблице, включая строковые, целочисленные и смешанные ключи. Порядок перебора нецелочисленных ключей не определён (порядок хеширования). Перебираются и массивная, и хеш-часть таблицы.
local config = {
host = "localhost",
port = 8080,
debug = true,
[1] = "first",
}
for key, value in pairs(config) do
print(key, value)
end
-- Prints all 4 entries in any orderipairs() для ключей массива
ipairs(t) перебирает целочисленные ключи, начиная с 1, и останавливается на первом значении nil. Такой перебор безопасен, предсказуем и сохраняет порядок. Используйте ipairs для таблиц, похожих на массивы, когда важен порядок и нужно остановиться на первой пропущенной позиции.
local fruits = {"apple", "banana", "cherry"}
for i, fruit in ipairs(fruits) do
print(i, fruit)
end
-- 1 apple
-- 2 banana
-- 3 cherry
-- stops at first nil
local t = {10, 20, nil, 40}
for i, v in ipairs(t) do
print(i, v) -- only 1,10 and 2,20
endpairs и ipairs
Важно понимать, когда что использовать: ipairs предназначен для упорядоченных последовательных массивов, а pairs — для словарей и смешанных таблиц. ipairs останавливается на первой пропущенной позиции со значением nil, а pairs посещает каждый ненулевой ключ. Для обычных массивов вариант ipairs более идиоматичен.
local mixed = {10, 20, key="val", 30}
-- ipairs only sees array part in order
print("ipairs:")
for i, v in ipairs(mixed) do
print(i, v) -- 1:10, 2:20, 3:30
end
-- pairs sees everything
print("pairs:")
for k, v in pairs(mixed) do
print(k, v) -- 1:10, 2:20, 3:30, key:val
endПользовательский итератор с замыканием
Вы можете написать собственный итератор в виде замыкания. Функция-фабрика возвращает замыкание, хранящее состояние и перемещающее позицию при каждом вызове. Когда возвращать больше нечего, оно возвращает nil, чтобы остановить обобщённый цикл for.
local function range(from, to, step)
step = step or 1
local i = from - step
return function()
i = i + step
if i <= to then return i end
end
end
for n in range(1, 10, 2) do
io.write(n .. " ")
end
print() -- 1 3 5 7 9string.gmatch как итератор
string.gmatch(s, pattern) возвращает итератор по всем совпадениям шаблона в строке s. Его часто используют для разделения строк, извлечения токенов или поиска всех вхождений шаблона.
local sentence = "the quick brown fox"
for word in string.gmatch(sentence, "%a+") do
print(word)
end
-- the
-- quick
-- brown
-- foxbreak в обобщённом цикле for
Обобщённый цикл for можно досрочно завершить с помощью break. Это полезно при поиске: перебирайте элементы, пока не найдёте совпадение, а затем выйдите из цикла. После выхода выполнение продолжается с инструкции после end.
local inventory = {
{name="sword", damage=50},
{name="shield", armor=30},
{name="bow", damage=35},
}
local target = "shield"
for i, item in ipairs(inventory) do
if item.name == target then
print("Found at index", i)
break
end
endИзменение таблиц во время перебора
Никогда не добавляйте и не удаляйте ключи таблицы во время перебора с помощью pairs() — поведение в этом случае не определено (какие-то изменения могут быть замечены, а другие пропущены). Если таблицу нужно изменить, соберите изменения во временный список и примените их после цикла.
local t = {a=1, b=2, c=3, d=4}
local toDelete = {}
-- Collect keys to delete
for k, v in pairs(t) do
if v % 2 == 0 then
toDelete[#toDelete+1] = k
end
end
-- Delete after iteration
for _, k in ipairs(toDelete) do
t[k] = nil
end
-- t = {a=1, c=3}Шаблон перечисления
Если нужны и индекс, и значение, используйте ipairs, который предоставляет оба. Если нужны только значения, а индекс не важен, для индекса можно использовать _ — это общепринятое имя переменной, значение которой не используется.
local colors = {"red", "green", "blue"}
-- With index
for i, color in ipairs(colors) do
print(i .. ": " .. color)
end
-- Ignore index with _
for _, color in ipairs(colors) do
print(color) -- just the values
endПрямой вызов next()
next(t, key) — базовая функция перебора. Она возвращает следующую пару «ключ-значение» после key или nil, если элементов больше нет. Вызов next(t, nil) возвращает первую запись. С помощью next(t) ~= nil можно проверить, что таблица не пуста, — это быстрее, чем подсчитывать элементы.
local function isEmpty(t)
return next(t) == nil
end
print(isEmpty({})) -- true
print(isEmpty({1,2,3})) -- false
print(isEmpty({a=1})) -- falseБыстрая проверка
Какой итератор останавливается на первой пропущенной позиции со значением nil в таблице?
Итоги: обобщённый цикл for и break
Краткое содержание:
pairs(t)— все ключи, в любом порядкеipairs(t)— целочисленные ключи от 1 до n, по порядку, с остановкой на nil- Пользовательские итераторы: возвращают замыкание, которое возвращает nil для остановки
breakдосрочно завершает цикл- Никогда не изменяйте таблицу во время перебора с pairs; собирайте изменения и применяйте их после
next(t) == nil— быстрая проверка на пустоту
Часто задаваемые вопросы
Урок «Обобщённый for и break» бесплатный?
Да — полный текст урока «Обобщённый for и break» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Обобщённый for и break»?
Используйте обобщённый for с pairs/ipairs и управляйте ходом цикла с помощью break. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Обобщённый for и break»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Инструкции if, elseif и else
- Циклы while и repeat-until
- Числовой цикл for
- Обобщённый for и break