2.4.5 – Оператор For
Оператор for допускает простую и расширенную формы записи.
В простой форме for выполняет блок кода до тех пор, пока переменная цикла,
изменяеющаяся в арифметической прогрессии, не достигнет установленного порога.
stat ::= for Name ' = ' exp ',' exp [', ' exp] do block end
block повторяется для переменной цикла name начиная
со значения первого выражения exp, до тех пор пока выполняется второе выражение exp с
шагом третьeго выражения exp.
Таким образом, запись
for v = e1, e2, e3 do block end
эквивалентна коду
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
block
var = var + step
end
end
Обратите внимание, что:
- Все три логических выражения
вычисляются только один раз перед началом цикла, причем полученные
значения должны быть числами.
- var,
limit, и step - неявные переменные,
мы условно именовали их здесь для объяснения логики работы
- Если выражение step (шаг) отсутствует,
то по умолчанию используется 1
- Для выхода из цикла for используйте break.
- Переменная v является локальной для цикла; вы не сможете использовать ее значение после выхода
из цикла for.
Если вам необходимо значение этой переменной, присвойте его другой
переменной перед выходом из цикла.
Расширенная форма оператора for реализована с использованием функций
итераторов. На каждом обороте для
получения нового значения переменной цикла вызывается итератор. Цикл заканчивается, когда итератор вернет nil.
Синтаксис расшеренного оператора for:
stat ::= for namelist in explist1 do block end
namelist ::= Name {', '~ Name}
Запись
for var_1, ···, var_n in explist do block end
можно представить как
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
var = var_1
if var == nil then break end
block
end
end
Заметим, что
- explist вычисляется только однажды. Его результатом является функция-итератор, таблица состояний и начальное значение индекса
- f,
s, и var неявные переменные, именованные здесь для примера
- Выйти из цикла можно с помощью оператора break.
- Переменная var_i является локальной; вы не
сможете использовать ее значение после выхода из for. Если вам необходимо ее
значение, заранее сохраните его в другой переменной.
|