无法在 event_handler lua 中使用导入的模块

我正在编写一个基础的 lua 事件处理程序,该程序使用位于另一个模块中的一些代码

require "caves"

script.on_event({defines.events.on_player_dropped_item}, function(e)
    caves.init_layer(game)
    player = game.players[e.player_index]
    caves.move_down(player)
end
)

但是每当事件被触发,我都会收到以下错误

attempt to index global 'caves' (a nil value)

这是为什么,我该如何解决?

点赞
用户8309054
用户8309054

require()函数不会自动创建全局表,它会将模块值返回到调用该函数的位置。要通过全局变量访问模块,你需要手动进行赋值:

local caves = require "caves"
2018-03-24 16:21:48
用户4687565
用户4687565

你打开相关模块并查看它导出了什么(文件底部分配了哪些全局变量和返回了哪些局部变量)。或者纠缠模块的作者创建接口。

Lua的require(filename)只会查找filename.lua文件并运行该文件,这代表了模块的初始化。如果运行文件时返回了任何内容,则会将其分配到Lua(不太隐藏的)表中(可能也可以说是require函数的缓存),如果没有返回任何内容但没有错误,则将布尔值true分配到该表中,以指示filename.lua已经在之前被加载过。左变量返回相同的true到等号中的变量中,如caves=require('caves')

其他任何事情都取决于作者的良心。

如果模块文件中的函数是这样写的(显示了两个变体):

init_layer = function(game)
    %做smth
end
function move_down(player)
    %做smth
end

那么在调用require之后,这些函数会在您的全局环境中,覆盖与同名变量。

如果它们像这样:

local init_layer = function(game)
    %做smth
end
local function move_down(player)
    %做smth
end

然后你就不会从外部获取它们了。

您的代码期望模块编写为:

caves = {
    init_layer = function(game)
        %做smth
    end
}
caves.move_down=function(player)
    %做smth
end

这是旧的模块编写方式,它目前已经过时,但没有被禁止。许多大型库(如torch)仍在使用它,因为您最终会将它们分配给同名全局变量。

Кирилл's的答案与较新的样式相关:

local caves={
%same as above
}
%same as above
return caves

我们在这里无法了解更多信息。其余的就取决于您,lua脚本本质上都是开源的。

附加说明:event_handler不是Lua语言的一部分,它是由嵌入Lua的主机程序提供的,因此相关标记是多余的。

您应该查阅软件文档,了解script.on_event在特定情况下的作用。一般来说,接受另一个函数作为参数的函数可以将其转储为字符串,然后尝试在不同的环境中加载并运行它,而不使用后者可能引用的upval和全局变量。

2018-03-25 10:32:00