繁体   English   中英

Lua-如何动态调用模块?

[英]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来看看。

  • 默认情况下, avarbvarcreate变量是全局变量,其他模块将看到它们。 大多数时候,您宁愿将它们设置为本地。

     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM