我正在阅读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
的剩余引用。
答案 0 :(得分:5)
如果TradeSkillFrame_LoadUI
是全局函数,则第一个语句在TradeSkillFrameReset
中捕获此函数。
TradeSkillFrame_LoadUI
的分配然后用新的函数替换全局函数,该函数首先通过TradeSkillFrameReset
引用调用原始函数。
这种模式被称为“函数挂钩”,here是关于一般技术和一些魔兽世界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()
这将打印以下输出:
我是原始的全球职能
这是修改过的......
作为旁注,Lua的名字是not all capitalized。
答案 1 :(得分:0)
在第一行,由于TradeSkillFrame_LoadUI
是非初始化变量,因此第一行:
TradeSkillFrameReset = TradeSkillFrame_LoadUI;
与制作相同:
TradeSkillFrameReset = nil
下面的函数没有进入无限循环,因为TradeSkillFrameReset实际上并没有“指向任何东西”。
我的猜测是,稍后在代码中,它会被正确初始化。像这样:
TradeSkillFrameReset = TradeSkillFrame_LoadUI;
TradeSkillFrame_LoadUI = function() -- 1. function declaration
TradeSkillFrameReset();
[...snip...]
end;
[... snip ...]
TradeSkillFrameReset = somethingElse -- 2. initialized to something else
TradeSkillFrame_LoadUI() -- 3. function invocation
技巧是你可以在1上定义一个函数,并在3上使用变量的值,同时在2上更改它。
如果这还不够明确,请告诉我。
答案 2 :(得分:0)
除非在您正在使用的环境中修改了全局变量的行为,否则该语句绝对没有任何内容。
local TradeSkillFrameReset = TradeSkillFrame_LoadUI
会产生影响,创建一个局部变量“slot”并使代码超过该点使用TradeSkillFrameReset的局部变量槽而不是为它进行全局变量查找。但是,正如你发布的代码一样,它只是将全局变量赋值为nil,这样就可以删除它,换句话说,如果它已经为零则没有效果。
可能存在的原因:
1)运行代码的环境在完成全局变量赋值时会执行一些特殊操作,而不是简单赋值的默认行为。我不认为这很可能,好像有任何特殊行为,查找nil TradeSkillFrame_LoadUI可能会导致错误。
2)最可能的原因仅仅是为了可读性。这是为了让您知道TradeSkillFrameReset 将正确分配给以后隐藏在代码中的某个地方,您将不会轻易注意到它。
答案 3 :(得分:0)
最重要的是Lua代码很容易将全局变量注入到其他Lua代码中。我已经使用了很多Lua,他们使用环境来添加全局变量。仅仅因为没有在该文件中定义var,最肯定的并不意味着它不存在。它甚至不必被定义为另一个文件中的全局变量,因为您可以以编程方式注入环境表,就像它是任何其他表一样。
答案 4 :(得分:-1)
我猜它会做类似于Javascript函数提升的东西,你可以在这里阅读:Referencing a JavaScript value before it is declared - can someone explain this