[英]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.