То, как язык управляет лексической областью, создает проблемы, включая goto
и continue
. Например,
local a=0
repeat
if f() then
a=1 --change outer a
end
local a=f() -- inner a
until a==0 -- test inner a
Объявление local a
внутри тела цикла маскирует внешнюю переменную с именем a
, и область действия этой локальной переменной распространяется на условие оператора until
, поэтому условие проверяет самый внутренний a
.
Если бы существовал continue
, его нужно было бы семантически ограничить, чтобы он действовал только после того, как все переменные, используемые в условии, вошли в область видимости. Это сложное условие документирования для пользователя и применения в компиляторе. Обсуждались различные предложения по этому вопросу, в том числе простой ответ о запрете continue
в стиле repeat ... until
loop. Пока что ни у одного из них не было достаточно убедительных вариантов использования, чтобы включить их в язык.
Обходной путь, как правило, заключается в том, чтобы инвертировать условие, которое приведет к выполнению continue
, и собрать остальную часть тела цикла при этом условии. Итак, следующий цикл
-- not valid Lua 5.1 (or 5.2)
for k,v in pairs(t) do
if isstring(k) then continue end
-- do something to t[k] when k is not a string
end
можно написать
-- valid Lua 5.1 (or 5.2)
for k,v in pairs(t) do
if not isstring(k) then
-- do something to t[k] when k is not a string
end
end
Это достаточно ясно и, как правило, не обременительно, если у вас нет серии тщательно продуманных элементов, управляющих работой цикла.