在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

点赞
stackoverflow用户312586
stackoverflow用户312586

在第一行中,由于 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 处进行更改。

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

2010-10-16 17:26:23
stackoverflow用户32203
stackoverflow用户32203

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

2010-10-16 17:30:42
stackoverflow用户450259
stackoverflow用户450259

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

local TradeSkillFrameReset = TradeSkillFrame_LoadUI

如果有影响的话,它将创建一个局部变量"slot",并使代码从那个点开始使用局部变量"slot"来代替全局变量的查找 TradeSkillFrameReset。然而,如果它在你发布的代码中,则只是将全局变量赋值为nil,这将使其被擦除,换句话说,如果它已经是nil,这没有任何影响。

它存在的原因:

1)代码运行的环境执行全局变量赋值时可能会做一些特殊处理,而不是简单赋值的默认行为。不过,我认为这不太可能,因为如果有任何特殊行为,nil 的 TradeSkillFrame_LoadUI 将可能会引起错误。

2)最可能的原因仅仅是为了可读性。它是为了让你知道 TradeSkillFrameReset _将_在稍后的代码中被正确赋值,隐蔽在你不太注意到的地方。

2010-10-16 19:16:50
stackoverflow用户175093
stackoverflow用户175093

如果 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 的名称不是全部大写的

2010-10-16 19:29:34
stackoverflow用户298661
stackoverflow用户298661

主要的问题是 Lua 代码能将全局变量注入到其他 Lua 代码中,我曾经使用许多需要使用环境添加全局变量的 Lua 代码。仅仅是因为一个变量在文件中没有定义并不意味着它不存在。它甚至不需要在另一个文件中定义为全局变量,因为你可以像处理其他表格一样通过程序将它注入到环境表格中。

2010-10-16 23:32:23