[英]Lua - How do I dynamically call a module?
这是我正在使用的一些非常简化的Lua代码。 我需要知道如何动态调用另一个模块(“斑马”):
avar = require "avar"
bvar = require "bvar"
function create(zebra)
print(zebra.new())
end
print(create(avar))
这是两个模块:
local Avar = {}
function Avar.new()
return "avar"
end
return Avar
local Bvar = {}
function Bvar.new()
return "new"
end
function Bvar.old()
return "old"
end
return Bvar
如果我尝试将字符串“ avar”传递给我的'create'函数,它将无法正常工作。 如果我输入不带引号的'avar'一词,它确实有效,但是,我不明白什么是不带引号的avar? 好像是一张空白的桌子? 不确定如何在我的主程序中将空白表作为参数传递。
但是也许我完全走错了道路。 如何动态调用模块?
不带引号的avar
是您创建的全局变量。 它被初始化为require
函数1返回的值,这是您正在调用的模块返回的值。 在这种情况下,其带有new
字段的表恰好是一个函数。
1在Lua中导入模块是通过常规函数而不是特殊语法完成的。 可以省略函数调用括号,因为如果使用单个参数编写函数调用并且该参数是字符串或表,则括号是可选的。
除此之外,这里还有其他一些令人困惑的事情:
您存储在avar
上的表不为空! 您可以通过for k,v in pairs(avar) do print(k,v) end
执行for k,v in pairs(avar) do print(k,v) end
来打印其内容for k,v in pairs(avar) do print(k,v) end
来看看。
默认情况下, avar
, bvar
和create
变量是全局变量,其他模块将看到它们。 大多数时候,您宁愿将它们设置为本地。
local avar = -- ... local bvar = -- ... local function create (zebra) -- ... end
create函数显然希望有一个表,因为它会对参数进行表索引(获取new
键并调用它)。 该字符串没有“新”键,因此无法使用。
您并不是真正地动态调用模块。 您需要以常规方式使用该模块,并且恰好将模块返回值传递给函数。
create
始终返回nil
所以执行print(create(avar))
没有意义。 您可能要修改create
以返回其对象,而不是打印它。
您可以要求任何时间:
function create(zebraModuleName)
zebraType = require(zebraModuleName)
print(zebraType .new())
end
print(create("avar"))
print(create("bvar"))
您可以使用lua语言中的标准require
,也可以使用元表/元方法构建自己的加载器。
1.创建全局函数:
function dynrequire (module)
return setmetatable ({},{
__index = function (table,key)
return require(module..'.'..key)
end
})
end
2.创建对package.path可见的项目树
./MySwiss/
\___ init.lua
\___ cut.lua
\___ glue.lua
\___ dosomething.lua
3.使模块动态化,您只需要将此行放在MySwiss/init.lua
(就像您命名一个PHP类一样):
return dynrequire('MySwiss')
4.要求模块并动态使用子属性在脚本上,您仅需要MySwiss和文件夹文件(或带有dynrequire('MySwiss.SubFolderName')
子文件夹。
var X = require('MySwiss')
X.glue()
请注意,MySwiss没有胶合键。 但是,当您尝试访问胶合键时,元方法__index会尝试需要子模块。 您可以使用此技术构建完整的项目树。 唯一的缺点是没有以这种方式打包的外部依赖项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.