Oop Lua-如何动态调用模块?
下面是我正在使用的一些非常相似的Lua代码。我需要知道如何动态调用另一个模块(“zebra”): 这里有两个模块:Oop Lua-如何动态调用模块?,oop,module,lua,Oop,Module,Lua,下面是我正在使用的一些非常相似的Lua代码。我需要知道如何动态调用另一个模块(“zebra”): 这里有两个模块: 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 如果我试图将字符串“a
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
function1返回的值,即您正在调用的模块返回的值。在本例中,它是一个带有new
字段的表,该字段恰好是一个函数
1在Lua中导入模块是通过常规函数而不是特殊语法完成的。可以使用函数调用括号,因为如果使用单个参数编写函数调用,并且该参数是字符串或表,则括号是可选的
除此之外,还有其他一些事情让你感到困惑:
- 您存储在
上的表不是空的!您可以通过对k,v成对执行avar
来查看来打印其内容(avar)do print(k,v)end
- 默认情况下,
、avar
和bvar
变量是全局变量,其他模块将看到这些变量。大多数情况下,你宁愿让他们成为本地人create
local avar = -- ... local bvar = -- ... local function create (zebra) -- ... end
- create函数显然需要一个表,因为它对其参数进行表索引(获取
键并调用它)。字符串没有“new”键,因此无法工作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。创建对包可见的项目树。路径
./MySwiss/
\___ init.lua
\___ cut.lua
\___ glue.lua
\___ dosomething.lua
3。使您的模块动态化
您只需要在MySwiss/init.lua
上放置这一行(就好像您在给一个PHP类命名一样):
4。需要您的模块并动态使用子属性
在脚本中,您只需要myswis和文件夹文件(或带有dynrequire('myswis.SubFolderName')
的子文件夹)
请注意,MySwiss没有胶水键。但是当您尝试访问胶水键时,metamethod\uuu索引尝试要求子模块。您可以使用此技术创建完整的项目树。唯一的缺点是外部依赖项没有以这种方式打包。感谢您所做的一切。我从整个程序中提取了这段代码,其中大部分功能n不在全局名称空间中。但是,我认为我的所有模块都不是本地的(根据您的第2点).问题:如何使模块成为本地模块?我应该在没有引号的情况下传递avar吗?根据第4点,我应该动态地要求吗?我只是在3个模块中的1个模块之间交替,所以我可以要求所有模块,但只想做正确的事情。谢谢帮助。@Kelly:尝试阅读Lua代码,而不是盲目地猜测该做什么。没有这样的问题作为本地模块的对象-可以是本地的或全局的对象是分配给模块表的值。(在本例中,
local avar=
vsavar=
)。至于选择要使用的模块,您可以加载所有模块,并使用if-else-if或哈希表选择其中一个值,或者您可以传递一个带有要请求的模块名称的变量,而不是传递一个文本字符串。虽然要求所有内容都比较简单,但我会这样做,除非它最终证明是性能问题。谢谢!Th这正是我需要的。
./MySwiss/
\___ init.lua
\___ cut.lua
\___ glue.lua
\___ dosomething.lua
return dynrequire('MySwiss')
var X = require('MySwiss')
X.glue()