为什么此函数作为全局变量而不是局部变量运行?

时间:2019-04-12 10:03:45

标签: variables lua global local metatable

将'eventHandlers.key_up'定义为全局工程,但将其定义为局部工程则不会。

local event = require "event"

local running = true

local function unknownEvent()
    --
end

local eventHandlers = setmetatable({}, { __index = function () return unknownEvent end })

function eventHandlers.key_up(addr, char, code, playerName)
    if (char == string.byte(" ")) then
      running = false
    end
end

local function handleEvent(eventID, ...)
    if (eventID) then
        eventHandlers[eventID](...)
    end
end

while running do
    handleEvent(event.pull ())
end

这是Minecraft的OpenComputers mod使用的示例事件处理程序。基本上,“事件”是一个库,可从计算机提取信号(在这种情况下为键盘输入),并告诉计算机如何处理事件。

程序基本上在底部的循环中等待,监听事件。本示例侦听“ key_up”事件。该事件还提供其他信息,例如键盘地址,按下的字符,按下它的玩家等。

在此示例中,在按下空格键(“ key_down”事件)后抬起空格键会中断底部的循环,程序会终止。

我对lua编码还比较陌生,我可以解决相对简单的代码,但是在这里我遇到了麻烦。我有两个问题:

(1)为什么将'eventHandlers.key_up'函数定义为全局函数,而不是将其定义为本地函数,为什么会起作用?

(2)在此代码中,元表的作用是什么?我一直在研究元表和元方法,但是发现它很难理解。

Open Computers - API:Event

我得到的错误是:

Line 11: '(' expected near '.'

1 个答案:

答案 0 :(得分:0)

eventHandlers在作用域中已经是本地的,所以:

function eventHandlers.key_up(addr, char, code, playerName)

…正在向该本地表添加函数。您也可以这样做:

eventHandlers.key_up = function(addr, char, code, playerName)

...这可能会使它更清晰一些。

重新元表:这里setmetatable返回一个空表,其中包含一个包含__index元方法的元表。每当您尝试访问表中未包含的字段时,就会调用__index元方法。

因此,在这里,如果您写eventHandlers.blah_blah(),Lua将在表中找不到blah_blah,因此将调用此__index元方法(如果存在),它将替换blah_blahunknownEvent一起使用,并称呼它是因为我们使用了括号。