我一直在努力为此找到答案但却没有这样做。我想知道,实际使用的do-end块是什么?它只是说在我的书中需要时使用值,所以我怎么能用它?
我是否通过在do-end循环中放置一个函数来使用它来减少局部变量的范围,并将局部变量放在函数之外但是在这个do-end块内部并且函数会看到变量?但是这个功能还可以被调用吗?
抱歉非常模糊。我希望这是有道理的。也许一个插图的例子可能有用^^
答案 0 :(得分:16)
do-end块与变量作用域的问题有关。基本上,当您使用标识符时,它具有什么价值?例如,当我们编写以下程序时会打印什么数字?
local x = 10
if x > 0 then
local x = 17
print(x)
end
print(x)
当谈到局部变量时,Lua使用标准的词法范围,正如Lua中的编程的section 4.2中所解释的那样。由于以下几个原因,词汇范围非常有用:
变量作用域是静态的。您只需查看源代码,您的代码中的每个标识符对应哪些变量和函数。这与您在Bash中找到的动态范围或通过方法调用或数组查找进行间接调度相反,您需要考虑程序的执行流程以了解最终会得到什么值。
变量范围有限,这有助于提高可读性并避免一些错误:
如果仅在需要使用变量时声明变量,则可以声明变量并同时对其进行初始化。另一方面,如果您在函数顶部声明所有变量,那么在初始化之前可能会意外地使用一个变量。
如果在内部范围内定义变量,则无法在外部范围内意外使用该变量。
当您将它与嵌套函数(闭包)结合使用时,词法作用域会启用一些very expressive idioms。
通常,您不必担心自己指定变量范围。函数,循环和条件会自动引入新的范围,这通常足以为变量提供良好的约束范围。也就是说,每隔一段时间,您可能想要凭空引入一些额外的范围,我们可以使用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块你明确表示你只运行那段代码一次。
答案 1 :(得分:10)
是的,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
仅来自该功能的visible,而不是其他任何地方。
答案 2 :(得分:9)
除了已经给出的好答案之外,我还想提一下在两个或多个函数之间共享私有变量的能力:
do
local i = 0
function inc()
i = i + 1
return i
end
function dec()
i = i - 1
return i
end
end