Циклы for: numeric и generic
Осваиваем два вида цикла for — по счётчику и по элементам таблицы.
Цикл for в Lua бывает двух видов: числовой (по диапазону чисел) и обобщённый (по элементам коллекции через функцию-итератор).
for — самый частый цикл на практике. В Lua у него две формы, и важно их не путать.
Числовой for (numeric for)
Числовой for идёт по диапазону: от начала до конца с заданным шагом:
for i = 1, 5 do
print(i)
endВывод:
1 2 3 4 5
Запись for i = 1, 5 означает «от 1 до 5 включительно». Можно задать шаг третьим числом:
for i = 10, 0, -2 do -- от 10 до 0, шаг -2
print(i)
endВывод:
10 8 6 4 2 0
Обобщённый for (generic for)
Обобщённый for перебирает элементы таблицы с помощью итератора. Для списков это ipairs, для словарей — pairs:
local colors = {"красный", "зелёный", "синий"}
for index, color in ipairs(colors) do
print(index, color)
endВывод:
1 красный 2 зелёный 3 синий
А вот перебор словаря через pairs:
local stats = {hp = 100, mp = 50}
for key, value in pairs(stats) do
print(key, value)
endВывод:
hp 100 mp 50
ipairs против pairs
| Итератор | Для чего | Порядок |
ipairs | списки (ключи 1, 2, 3...) | строгий, по возрастанию |
pairs | любые таблицы | не гарантирован |
Как работает под капотом
Числовой for вычисляет границы и шаг один раз в начале — менять их внутри цикла бесполезно. Обобщённый for на каждой итерации вызывает функцию-итератор (ipairs/pairs), которая возвращает следующую пару; когда возвращается nil — цикл заканчивается.
Частые ошибки
- Думать, что
for i = 1, 5идёт до 4 (как в языках с верхней границей-исключением). В Lua граница включительна. - Использовать
ipairsдля словаря со строковыми ключами — он ничего не переберёт. - Менять переменную счётчика внутри числового
forи ждать эффекта — границы уже зафиксированы.
Итог
- Числовой
for i = start, stop, stepидёт по диапазону, граница включительна. - Обобщённый
for ... in ipairs/pairsперебирает элементы таблицы. ipairs— для списков в строгом порядке,pairs— для любых таблиц без гарантии порядка.- Границы числового
forвычисляются один раз в начале цикла.