为什么在Lua中使用do结束块?
我一直试图找到答案,但没有找到。我想知道,do end block实际上是用来做什么的?它只是说在我的书中需要时使用值,那么我如何使用它呢 我是否使用它来减少局部变量的范围,方法是将函数放在Do end循环中,并将局部变量放在函数外部,但放在Do end块中,函数将看到这些变量?但是这个函数还能被调用吗为什么在Lua中使用do结束块?,lua,block,scoping,Lua,Block,Scoping,我一直试图找到答案,但没有找到。我想知道,do end block实际上是用来做什么的?它只是说在我的书中需要时使用值,那么我如何使用它呢 我是否使用它来减少局部变量的范围,方法是将函数放在Do end循环中,并将局部变量放在函数外部,但放在Do end块中,函数将看到这些变量?但是这个函数还能被调用吗 抱歉说得太含糊了。我希望这是有道理的。也许举例说明可能有用^^是的,do end块可用于限制变量的范围;要使使用这些变量的函数保持可见,您有几个选项 本地化将函数保持在块之外的变量: local
抱歉说得太含糊了。我希望这是有道理的。也许举例说明可能有用^^是的,
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 x = 10
if x > 0 then
local x = 17
print(x)
end
print(x)
当谈到局部变量时,Lua使用标准的词法作用域,这在Lua书中的编程部分中有很好的解释。词法范围非常有用,原因如下:
- 变量作用域是静态的。通过查看源代码,您就知道哪些变量和函数对应于代码中的每个标识符。这与Bash中的动态作用域相反,或者通过方法调用或数组查找进行间接调度,在这里,您需要考虑程序的执行流,以知道最终会得到什么值
- 变量范围有限,这有助于提高可读性并避免一些错误:
- 如果只在需要使用变量时才声明变量,则可以同时声明和初始化它。另一方面,如果在函数顶部声明所有变量,那么在初始化之前可能会意外地使用一个变量
- 如果在内部作用域中定义变量,则不能意外地在外部作用域中使用它
- 当您将词法作用域与嵌套函数(闭包)结合使用时,它会启用一些功能
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)"
也就是说,doend不需要经常使用。如果代码块较小,则不需要隐藏局部变量,如果代码块较大,则将代码块放入其自身的子例程中通常是更好的方法。我发现do end非常出色的时候,你只需要做一次计算——函数可能会被调用很多次,但如果你使用do end块,你会清楚地表明你只运行了一次代码。除了已经给出的好答案,我想提及在两个或多个函数之间共享私有变量的能力:
do
local i = 0
function inc()
i = i + 1
return i
end
function dec()
i = i - 1
return i
end
end