这是我正在使用的一些非常简化的Lua代码。我需要知道如何动态调用另一个模块('zebra'):
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?这似乎是一张空白的桌子?不知道如何在我的主程序中将空白表作为参数传递。
但也许我完全走错了路。如何动态调用模块?
答案 0 :(得分:2)
avar
是您创建的全局变量。它被初始化为require
函数 1 返回的值,这是您正在调用的模块返回的值。在这种情况下,它是一个恰好是函数的new
字段的表。
1 在Lua中导入模块是通过常规函数而不是特殊语法完成的。可以省略函数调用括号,因为如果使用单个参数编写函数调用并且该参数是字符串或表,则parens是可选的。
除此之外,还有其他一些令你困惑的事情:
您在avar
上存储的表格不是空的!您可以通过执行for k,v in pairs(avar) do print(k,v) end
来打印其内容。
默认情况下,avar
,bvar
和create
变量是全局变量,其他模块会看到这些变量。大多数时候你宁愿把它们变成本地的。
local avar = -- ...
local bvar = -- ...
local function create (zebra)
-- ...
end
create function显然需要一个表,因为它对其参数进行表索引(获取new
键并调用它)。该字符串没有“新”键,因此无法使用。
您并非真正动态调用模块。您需要以常规方式使用该模块,并且只是将模块返回值传递给函数。
create
始终返回nil
,因此print(create(avar))
没有意义。您可能希望修改create
以返回其对象而不是打印它。
答案 1 :(得分:1)
您可以随时要求:
function create(zebraModuleName)
zebraType = require(zebraModuleName)
print(zebraType .new())
end
print(create("avar"))
print(create("bvar"))
答案 2 :(得分:0)
您可以使用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会尝试需要子模块。您可以使用此技术构建完整的项目树。唯一的缺点是没有这样包装外部依赖项。