Зачем использовать блок do-end в Lua?
Я продолжаю пытаться найти ответы на это, но не могу этого сделать. Я хотел знать, для чего на самом деле используется блок do-end? Он просто говорит, что значения используются, когда это необходимо в моей книге, так как я могу использовать это?
использую ли я его для уменьшения области локальных переменных, помещая функцию в цикл do-end и помещая локальные переменные вне функции, но внутри этого блока do-end, и переменные будут видны функции? Но тогда функция все еще может быть звонил?
извините за очень расплывчато. Надеюсь, в этом есть смысл. Возможно, иллюстрированный пример может быть полезен ^^
3 ответов
блоки 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 не нужно использовать так часто. Если блок кода небольшой, то меньше необходимости скрывать локальные переменные, и если блок кода большой, часто лучше поместить блок кода в собственную подпрограмму. Время, когда я нахожу, что do-end сияет, когда вам нужно только выполнить вычисление один раз - функции потенциально могут быть вызваны много раз, но если вы используете блок do-end, вы ясно даете понять, что вы только запускаете этот кусок кода один раз.
да do end
блок может использоваться для ограничения области переменных; чтобы сохранить функцию, которая использует эти переменные видимыми, у вас есть несколько опций
-
локализовать переменную, которая удерживает функцию вне блока:
local func do local a = 0 func = function(inc) a = a + inc return a end end
-
использовать глобальную функцию:
do local a = 0 function func(inc) a = a + inc return a end end
-
использовать метод:
local tbl = {} do local a = 0 function tbl:func(inc) a = a + inc return a end end
во всех трех случаях вы все еще можете позвонить func()
после блока закрыто, но a
только видимого из этой функции и нигде больше.
в дополнение к хорошим ответам, уже данным, я хочу упомянуть возможность поделиться частной переменной среди двух или более функций:
do
local i = 0
function inc()
i = i + 1
return i
end
function dec()
i = i - 1
return i
end
end