我正在仔细阅读LUA代码文件,文件的顶部包含:

    1  | TradeSkillFrameReset = TradeSkillFrame_LoadUI;
    2  | 
    3  | TradeSkillFrame_LoadUI = function()
    4  |    TradeSkillFrameReset();
            ...
    112|    TradeSkillFrame_LoadUI = TradeSkillFrameReset;
            ...
    114| end;

他们正在做任务的第一行:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

在代码文件中的这一点上,他们分配了未销售的标识符(TradeSkillFrame_LoadUI)到未宣布的变量(TradeSkillFrameReset)。这在卢阿允许吗?

  • 变量声明是隐式的吗?
  • 是否都认为所有未申报的标识符是正向声明?

更令人困惑的是第一个 TradeSkillFrame_LoadUI 似乎要做的就是呼唤自己:

TradeSkillFrame_LoadUI = function()
   TradeSkillFrameReset();

这不是无限循环?


编辑: 添加了剩余的参考 TradeSkillFrameResetTradeSkillFrame_LoadUI.

有帮助吗?

解决方案

如果 TradeSkillFrame_LoadUI 是全局函数,第一个语句在 TradeSkillFrameReset.

TradeSkillFrame_LoadUI 然后用新功能替换全局函数,该功能首先通过 TradeSkillFrameReset 参考。

该模式称为“函数钩”, 这里 是有关通用技术的更多信息和魔兽世界的某些世界特定细节(根据该功能的名称,该脚本可能来自何处)

一些示例代码,以说明这一点:

function SomeGlobalFunction()
    print("I'm the original global function")
end

OrigFunction = SomeGlobalFunction

SomeGlobalFunction = function()
    OrigFunction()
    print("And here's the modfied one...")
end

--...
SomeGlobalFunction()

这将打印以下输出:

我是原始的全球功能

这是一个适应的人...

旁注,卢阿的名字是 并非全部大写.

其他提示

在第一行,自 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上的变量值。

让我知道这是否还不够清晰。

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

local TradeSkillFrameReset = TradeSkillFrame_LoadUI

会产生效果,创建一个局部变量的“插槽”,并使代码超过该点,将局部变量插槽用于TradeSkillFramerEset,而不是为其进行全局变量查找。但是,正如您发布的代码中一样,它只是将全局变量分配给nil,换句话说,它的效果是将其删除,如果它已经是零,则不会效果。

理由可能存在:

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

2)最可能的原因仅仅是出于可读性。这是为了让您知道Tradeskillframereset 将要 正确地分配给后来埋葬在代码中的某个地方,您将不会随时注意到它。

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

我猜想它做的类似于JavaScript的功能提升的操作,您可以在这里阅读: 在声明javascript值之前引用javascript值 - 有人可以解释一下

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top