首页 > 解决方案 > 为什么这个函数作为全局变量运行,而不是作为局部变量运行?

问题描述

将“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) 元表在这段代码中的作用是什么?我一直在研究元表和元方法,但我发现它很难掌握。

打开计算机 - API:事件

我得到的错误是这样的:

Line 11: '(' expected near '.'

标签: variablesluagloballocalmetatable

解决方案


该表eventHandlers在范围内已经是本地的,因此:

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

…正在向这个本地表添加一个函数。你也可以这样做:

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

......这可能会让这更清楚一点。

Re metatables:这里setmetatable返回一个空表,其中包含一个包含元方法的元表__index__index每当您尝试访问不在表中的字段时,都会调用元方法。

所以这里如果你写eventHandlers.blah_blah(),Lua 不会在表中找到,所以如果它存在blah_blah就会调用这个元方法,它会替换为并调用它,因为我们使用了括号。__indexblah_blahunknownEvent


推荐阅读