在Lua中,将一个未定义的标识符分配给一个未声明的变量是什么意思?
我正在浏览一个Lua代码文件,文件的顶部包含以下内容:
1 | TradeSkillFrameReset = TradeSkillFrame_LoadUI;
2 |
3 | TradeSkillFrame_LoadUI = function()
4 | TradeSkillFrameReset();
...
112| TradeSkillFrame_LoadUI = TradeSkillFrameReset;
...
114| end;
他们在第一行进行了一个赋值操作:
TradeSkillFrameReset = TradeSkillFrame_LoadUI;
在此代码文件中,他们将一个未声明的标识符(TradeSkillFrame_LoadUI
)分配给一个未声明的变量(TradeSkillFrameReset
)。Lua允许吗?
- 变量声明是否是隐式的?
- 所有未声明的标识符都假定为前向声明吗?
更令人困惑的是,第一个TradeSkillFrame_LoadUI
似乎要做的就是调用自身:
TradeSkillFrame_LoadUI = function()
TradeSkillFrameReset();
这不是一个无限循环吗?
编辑:添加到“TradeSkillFrameReset”和“TradeSkillFrame_LoadUI”的所有其他引用。
原文链接 https://stackoverflow.com/questions/3949534
我猜它正在做类似于 JavaScript 的函数提升,你可以在这里阅读:引用尚未声明的 JavaScript 值 - 有人能解释一下吗。
除非你正在使用的环境已经修改了全局变量的行为,否则该语句绝对不会有任何作用。
local TradeSkillFrameReset = TradeSkillFrame_LoadUI
如果有影响的话,它将创建一个局部变量"slot",并使代码从那个点开始使用局部变量"slot"来代替全局变量的查找 TradeSkillFrameReset。然而,如果它在你发布的代码中,则只是将全局变量赋值为nil,这将使其被擦除,换句话说,如果它已经是nil,这没有任何影响。
它存在的原因:
1)代码运行的环境执行全局变量赋值时可能会做一些特殊处理,而不是简单赋值的默认行为。不过,我认为这不太可能,因为如果有任何特殊行为,nil 的 TradeSkillFrame_LoadUI 将可能会引起错误。
2)最可能的原因仅仅是为了可读性。它是为了让你知道 TradeSkillFrameReset _将_在稍后的代码中被正确赋值,隐蔽在你不太注意到的地方。
如果 TradeSkillFrame_LoadUI
是全局函数,第一条语句将在 TradeSkillFrameReset
中捕获该函数。
然后,对 TradeSkillFrame_LoadUI
的赋值将用一个新的函数替换全局函数,新的函数首先通过 TradeSkillFrameReset
引用调用原始函数。
这种模式称为“函数钩子”,这里 有关于一般技术和一些特定于 World of Warcraft Lua 环境的详细信息(该脚本可能来自于该函数的名称)。
以下是一个示例代码,以便更好地说明:
function SomeGlobalFunction()
print("I'm the original global function")
end
OrigFunction = SomeGlobalFunction
SomeGlobalFunction = function()
OrigFunction()
print("And here's the modfied one...")
end
--...
SomeGlobalFunction()
这将输出以下内容:
I'm the original global function
And here's the modfied one...
顺便提一下,Lua 的名称不是全部大写的。
主要的问题是 Lua 代码能将全局变量注入到其他 Lua 代码中,我曾经使用许多需要使用环境添加全局变量的 Lua 代码。仅仅是因为一个变量在文件中没有定义并不意味着它不存在。它甚至不需要在另一个文件中定义为全局变量,因为你可以像处理其他表格一样通过程序将它注入到环境表格中。
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
在第一行中,由于
TradeSkillFrame_LoadUI
是一个非初始化变量,因此这一行:TradeSkillFrameReset = TradeSkillFrame_LoadUI;
相当于:
TradeSkillFrameReset = nil
下面的函数不会进入无限循环,因为此时
TradeSkillFrameReset
实际上还没有“指向任何东西”。我猜测在代码的后面部分,它会得到正确的初始化。就像这样:
TradeSkillFrameReset = TradeSkillFrame_LoadUI; TradeSkillFrame_LoadUI = function() -- 1. 函数声明 TradeSkillFrameReset(); [... 剪辑 ...] end; [... 剪辑 ...] TradeSkillFrameReset = somethingElse -- 2. 初始化为其他内容 TradeSkillFrame_LoadUI() -- 3. 函数调用
关键在于你可以在 1 处定义一个函数,并在 3 处使用变量的值,同时在 2 处进行更改。
如果这不够清楚,请告诉我。