0

我正在阅读一个 Lua 代码文件,文件的最顶部包含:

    1 | TradeSkillFrameReset = TradeSkillFrame_LoadUI;
    2 |
    3 | TradeSkillFrame_LoadUI = 函数()
    4 | TradeSkillFrameReset();
            ...
    112| TradeSkillFrame_LoadUI = TradeSkillFrameReset;
            ...
    114| 结尾;

他们在做作业的第一行:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

在代码文件的这一点上,他们将一个未声明的标识符 ( TradeSkillFrame_LoadUI) 分配给一个未声明的变量 ( TradeSkillFrameReset)。这在 Lua 中是否允许?

  • 变量声明是隐式的吗?
  • 是否所有未声明的标识符都假定为前向声明?

更令人困惑的是,第一个TradeSkillFrame_LoadUI似乎做的是调用自己:

TradeSkillFrame_LoadUI = function()
   TradeSkillFrameReset();

这怎么不是无限循环?


编辑:TradeSkillFrameReset添加了对和的剩余引用TradeSkillFrame_LoadUI

4

5 回答 5

5

IfTradeSkillFrame_LoadUI是一个全局函数,第一条语句在TradeSkillFrameReset.

然后赋值TradeSkillFrame_LoadUI将全局函数替换为一个新函数,该函数首先通过TradeSkillFrameReset引用调用原始函数。

这种模式被称为“函数挂钩”,这里有一些关于一般技术的更多信息和一些魔兽世界 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 的名称并非全部大写

于 2010-10-16T19:29:34.540 回答
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 上更改它。

如果这还不够清楚,请告诉我。

于 2010-10-16T17:26:23.230 回答
0

除非在您正在使用的环境中修改了全局变量的行为,否则该语句绝对不会执行任何操作。

local TradeSkillFrameReset = TradeSkillFrame_LoadUI

会产生效果,创建一个局部变量“slot”并使代码超过该点使用TradeSkillFrameReset的局部变量slot,而不是对其进行全局变量查找。但是,就像在您发布的代码中一样,它只是将全局变量分配给 nil,这具有擦除它的效果,换句话说,如果它已经是 nil,则没有效果。

它可能存在的原因:

1)当全局变量赋值完成时,代码运行的环境会做一些特殊的事情,而不是简单赋值的默认行为。我认为这不太可能,好像有任何特殊行为一样,查找 nil TradeSkillFrame_LoadUI 可能会导致错误。

2)最可能的原因仅仅是为了可读性。这是为了让您知道 TradeSkillFrameReset被正确分配到稍后隐藏在代码中您不会轻易注意到它的某个地方。

于 2010-10-16T19:16:50.290 回答
0

最主要的是 Lua 代码很容易将全局变量注入到其他 Lua 代码中。我使用了很多 Lua,他们使用环境来添加全局变量。仅仅因为 var 没有在该文件中定义,并不意味着它不存在。它甚至不必在另一个文件中定义为全局变量,因为您可以以编程方式将其注入环境表,就像它是任何其他表一样。

于 2010-10-16T23:32:23.490 回答
-1

我猜它做的事情类似于 Javascript 的函数提升,你可以在这里阅读:在声明之前引用 JavaScript 值 - 有人可以解释一下吗

于 2010-10-16T17:30:42.730 回答