在Lua中为什么要使用do-end块?
我一直试图找到关于这个问题的答案,但一直失败。我想知道,do-end
块实际上是用来干什么的?我的书里只是说在需要时使用值,那我该怎么用呢?
我是不是应该把一个函数放在do-end
循环中,通过在函数外部但在这个do-end
块内放置局部变量来缩小局部变量的作用域,并且函数能够看到这些变量?但是,函数还能被调用吗?
很抱歉表达得非常含糊。我希望这有意义。也许一个具体的例子会更有用~~
原文链接 https://stackoverflow.com/questions/23895406
do-end
块与变量作用域的问题有关。实际上,当你使用一个标识符时,它有什么值?例如,当我们编写以下程序时,会打印出什么数字?
local x = 10
if x > 0 then
local x = 17
print(x)
end
print(x)
对于局部变量,Lua 使用标准的词法作用域,这在《Programming in Lua》书的第 4.2 小节中解释得很好。词法作用域有几个非常有用的原因:
变量作用域是静态的。通过查看源代码,您可以知道您的代码中每个标识符对应的变量和函数。这与在 Bash 中找到的动态作用域或通过方法调用或数组查找进行间接调度的情况相反,在这种情况下,您需要考虑程序的执行流程才能知道最终得到的值。
变量作用域是有限的,这有助于可读性并避免一些错误:
如果只有在需要使用变量时才声明变量,则可以同时声明和初始化变量。另一方面,如果在函数顶部声明所有变量,则可能会在初始化变量之前意外地使用变量。
如果在内部作用域内定义变量,则不能在外部作用域中意外地使用它。
词法作用域结合嵌套函数(闭包)时,启用了一些非常表达性的惯用语法。
通常,您不需要担心自己指定变量作用域。函数、循环和条件语句会自动引入新的作用域,这通常足以为您的变量提供明确的作用域。话虽如此,偶尔您可能需要在无中生有地引入一些额外的作用域,这时可以使用 do-end
。《Programming Lua》有以下示例,其中您想计算二次方程的解,计算中有一些暂存变量:
do
local a2 = 2 * a
local d = sqrt(b^2 - 4 * a * c)
x1 = (-b + d) / a2
x2 = (-b - d) / a2
end -- `a2' 和 `d' 的作用域在此处结束
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) -- 糟糕!我想说 "print(a)"
话虽如此,do-end
并不需要经常使用。如果代码块很小,隐藏局部变量的需求就不那么大;如果代码块很大,将代码块放入自己的子例程中通常是更好的方法。我觉得 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
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
是的,
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
仅在该函数中可见,而不是在任何其他地方。