【问题标题】:Why does this function run as a global variable, but not as a local one?为什么这个函数作为全局变量运行,而不是作为局部变量运行?
【发布时间】:2019-04-12 10:03:45
【问题描述】:

将 '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 模组的示例事件处理程序。 “事件”基本上是一个库,它从计算机中提取信号(在本例中为键盘输入)并告诉计算机如何处理该事件。

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

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

我对 lua 编码比较陌生,我可以处理相对简单的代码,但是在这里我被卡住了。我有两个问题:

(1) 为什么在'eventHandlers.key_up'函数定义为全局的时候可以,而定义为局部的时候不行?

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

Open Computers - API:Event

我得到的错误是这样的:

Line 11: '(' expected near '.'

【问题讨论】:

    标签: variables lua global local metatable


    【解决方案1】:

    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,所以如果存在就会调用这个__index 元方法,这会将blah_blah 替换为unknownEvent 并调用它,因为我们使用了括号。

    【讨论】:

    • 啊,我明白了,所以将其定义为本地行不通,因为它本身并不是真正的变量?这是一个表格条目,恰好是一个函数?
    • 是的,就是这样!
    猜你喜欢
    • 2021-06-20
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多