为什么它不能是本地的?
这是我正在运行的安装程序的一个虚拟版本。启动程序函数似乎没有看到 GetLevel。起码第一个打印是看得见的,但第二个不是。所以函数从未开始。是因为代码在它在代码中被启动的地方之后出现,而在 Launcher 执行它的时候它还不存在吗?当我移除本地标记时,它可以工作。所以全局函数可以从脚本的任何地方“看到”,但本地函数只能从代码的后面“看到”? 我试图找出哪些函数可以进行本地化,因为它们都是当前全局的。这有什么好处吗-一个在整个脚本中本地的函数和一个不本地的函数之间有什么区别吗?
local UseLevel = true
local Limit = 0
local function Launcher()
print("现在尝试启动 GetLevel")
GetLevel()
end
local function GetLevel()
print("GetLevel 已启动")
if UseLevel then
Limit = 4
else
Limit = 5
end
end
原文链接 https://stackoverflow.com/questions/71102432
使用局部变量的好处有两个:
第一,局部变量通常更快,因为它们只使用 Lua 虚拟机中的寄存器,而全局变量是全局表中的条目(实际上是哈希表)。调用全局函数需要先索引哈希表。
第二,局部变量有助于提高代码质量,因为它们仅在其局部作用域中可见(比如在文件中或甚至在 if-branch、循环等中)。把所有东西都放在全局作用域中被称为“全局污染”,这是不被赞同的。它也会减慢全局访问速度,因为它会使全局表膨胀。需要注意的是,Lua 允许使用 _ENV
(或在旧版中使用 setfenv
)来改变环境,因此您有时可以在不污染全局环境的情况下使用这个方法来省略局部关键字和前向声明。通常情况下,您不应该改变环境。
常常使用全局变量来公开接口,正如Nicol Bolas所指出的那样。您也可以在文件末尾使用 return my_api_table
,API表可以使用local my_api_table = require(relative_path)
进行“导入”。
那是因为代码在启动它的位置之后才出现在代码中,在启动程序执行它的时候它还不存在吗?
是的。您可以使用“前向局部声明”GetLevel
来解决这个问题:
local UseLevel = true
local Limit = 0
local GetLevel -- "前向声明"在Launcher之前
local function Launcher()
print("trying to launch GetLevel now")
GetLevel()
end
-- 这与 GetLevel = function() ... end 相同,因此不设置全局变量,而是分配给先前声明的局部变量 GetLevel
function GetLevel()
print("GetLevel was launched")
if UseLevel then
Limit = 4
else
Limit = 5
end
end
将 Launcher
函数简单地放在 GetLevel
之后也可以:
local UseLevel = true
local Limit = 0
local function GetLevel()
print("GetLevel was launched")
if UseLevel then
Limit = 4
else
Limit = 5
end
end
local function Launcher()
print("trying to launch GetLevel now")
GetLevel()
end
其他人已经告诉你一些关于局部变量和全局变量的一般知识。让我们看看你的代码并理解为什么它不起作用。
local UseLevel = true
local Limit = 0
local function Launcher()
print("trying to launch GetLevel now")
GetLevel()
end
以上你定义了三个本地变量。一个布尔值,一个数字和一个函数值。 Launcher
调用 GetLevel
,假设这是您执行的唯一代码,那么它是一个全局 nil 值。因为在那一行之前,你既没有定义一个名字为GetLevel
的本地变量也没有定义一个全局变量。如果你从未为变量分配过值,那么它就是一个 nil 值,如果你从未声明该变量为本地变量,它就是一个全局 nil 值。
然后,您定义了一个名为GetLevel
的本地函数。这是一个新的本地变量。它不是你在定义 Launcher 时使用的那个 GetLevel
。因为那是全局变量。
local function GetLevel()
print("GetLevel was launched")
if UseLevel then
Limit = 4
else
Limit = 5
end
end
因此,当你稍后调用 Launcher
时,它仍将使用全局 nil 值。而不是它完全不知道的本地值。
使此方法工作的唯一方法是将函数值分配给在 Launcher
定义中使用的相同变量。只要引用相同,范围无关紧要。仅以本地方式使此方法工作的唯一方法是在定义 Launcher
之前声明该本地引用。
无论您是在 Launcher
之前还是之后定义 GetValue
,只要在调用 Launcher
时已经定义就可以。
- 求解,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 模式将字符串(嵌套数组)转换为真正的数组?
- 如何创建一个 lua 脚本以针对特定键为 fluentbit 进行限流
所以全局函数可以从脚本中的任何位置“看到”,但本地函数只能从代码后面看到?
是的,“全局”意味着全局。
如果您不希望某些内容在脚本外可见,则将其设置为本地内容。除非外部世界需要查看某些内容,否则脚本不应将其暴露给外部世界。只暴露接口,也就是外部代码实际会使用的东西。