Циклы 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 вычисляются один раз в начале цикла.
Проверьте себя
1. До какого значения дойдёт цикл for i = 1, 5 do?
AДо 4 (граница не включается)
BДо 5 включительно
CДо 6
DБесконечно
2. Какой итератор использовать для перебора словаря со строковыми ключами?
Aipairs
Bpairs
Cnext только вручную
Dnumeric for
3. Как задать шаг -2 в числовом for от 10 до 0?
Afor i = 10, 0 step -2
Bfor i = 10, 0, -2 do
Cfor i = 10 to 0 by -2
Dfor i = -2, 10, 0