Ответ 1
Блоки do-end связаны с проблемой изменения переменных. По сути, когда вы используете идентификатор, какое значение оно имеет? Например, какие числа будут напечатаны при написании следующей программы?
local x = 10
if x > 0 then
local x = 17
print(x)
end
print(x)
Когда дело доходит до локальных переменных, Lua использует стандартную лексическую область, как это хорошо объясняется в разделе 4.2 в Программе в книге Lua. Лексическая область очень полезна по нескольким причинам:
-
Скольжение переменной статично. Вы знаете, просто посмотрев исходный код, какие переменные и функции соответствуют каждому идентификатору в вашем коде. Это противоречит динамическому охвату, который вы найдете в Bash или косвенной диспетчеризации через вызовы методов или поиска массивов, где вам нужно подумать о потоке выполнения программы, чтобы узнать, какое значение вы в конечном итоге получите.
-
Ограничение переменных ограничено, что помогает читать и позволяет избежать некоторых ошибок:
-
Если вы объявляете переменную только тогда, когда вам нужно ее использовать, вы можете объявить ее и инициализировать ее одновременно. С другой стороны, если вы объявите все свои переменные в верхней части функции, вы можете случайно случайно использовать ее перед ее инициализацией.
-
Если вы определяете переменную внутри внутренней области, вы не можете случайно использовать ее во внешних областях.
-
-
Лексическое определение позволяет некоторым очень выразительным идиомам, когда вы объединяете его с вложенными функциями (замыканиями).
Обычно вам не нужно беспокоиться о том, чтобы сами определять области переменных. Функции, циклы и условные обозначения автоматически вводят новые области видимости, и этого обычно достаточно, чтобы дать вашим переменным хорошо ограниченную область. Тем не менее, время от времени вы можете ввести некоторые дополнительные области из воздуха, и для этого мы можем использовать do-end. Программирование Lua имеет следующий пример, где вы хотите вычислить решения квадратичного уравнения, и вычисление имеет некоторые временные:
do
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
end -- scope of `a2' and `d' ends here
print(x1, x2)
Без блока do-end a2
и d
могут быть случайно использованы после того, как они больше не нужны:
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
print(x1, x2)
print(a2) -- OOPS! I wanted to say "print(a)"
Тем не менее, do-end не нужно часто использовать. Если блок кода мал, меньше необходимости скрывать локальные переменные, и если блок кода большой, часто это лучший подход, чтобы поместить блок кода в свою собственную подпрограмму. Время, когда я нахожу, что штрих-код заканчивается, когда вам нужно всего лишь выполнить вычисление один раз, функции можно потенциально вызывать много раз, но если вы используете блок завершения, вы даете понять, что вы используете только этот фрагмент кода один раз.