一、模塊機(jī)制module
創(chuàng)新互聯(lián)建站是一家專業(yè)提供柳江企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、H5建站、小程序制作等業(yè)務(wù)。10年已為柳江眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。1.什么是module
對(duì)于用戶來說,一個(gè)module相當(dāng)于一個(gè)so庫。模塊的主要目標(biāo)是實(shí)現(xiàn)代碼的共享。
2.如何編寫module
lua是通過table來實(shí)現(xiàn)模塊的,典型的寫法如下。
local M = {} ---- 通常是加local的,如果不加,則M默認(rèn)注冊(cè)到_G中,require后,即使不return也可以直接使用M。加了local是局部變量,需要顯示的return一下。
M.print = function(...)
print(...)
end
return M
二、require機(jī)制
1.require實(shí)現(xiàn)原理:
function require(name)
if not packge.loaded[name] then ---- 避免重復(fù)加載
local loader = findloader(name) ---- 如果是so,就以loadlib方式加載文件,如果是lua文件,就以loadfile方式加載文件。
if loader == nil then
error("unable to load module " .. name)
end
package.loaded[name] = true ---- 將模塊標(biāo)記為以加載,我們有時(shí)候會(huì)看到require返回true的現(xiàn)象,是由于被調(diào)用的模塊,沒有顯示的執(zhí)行package.loaded[modname] = M或者給出return M這樣的返回值。
local res = loader(name) ---- require會(huì)以name作為入?yún)韴?zhí)行該文件,如果有返回結(jié)果,就將返回結(jié)果保存在package.loaded[name]中,如果沒有返回結(jié)果,就直接返回package.loaded[name]。如果我們?cè)诒徽{(diào)用的文件中直接寫明return 1。則調(diào)用者的require的返回結(jié)果就是1。但是只要我們顯示的在require文件中寫明了_G[modname] = M,我們?nèi)匀豢梢栽趓equire之后,直接使用M作為名字來調(diào)用,是由于將M加入到了_G中。
if res ~= nil then
package.loaded[name] = res
end
end
return package.loaded[name]
end
2.require實(shí)現(xiàn)解析:
傳參: require會(huì)將模塊名作為參數(shù)傳遞給模塊
返回值:如果一個(gè)模塊沒有返回值的話,require就會(huì)返回package.loaded[modulename]作為返回值。
------------------------example---------------------
舉例:
pa.lua:
local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M
function M.print_mob()
print(modname)
end
mob.lua:
require "pa"
pa.print_mob()
執(zhí)行結(jié)果:
lua mob.lua
pa
------------------------------------------------------------
分析:
pa.lua中的modname接收的是require傳遞過來的參數(shù),將其加入到全局環(huán)境變量_G中,相當(dāng)于動(dòng)態(tài)創(chuàng)建了一個(gè)modname的表(注意:表名的賦值實(shí)際上是引用,相當(dāng)于C語言中的指針,即使是傳參也會(huì)有相同的效果)。我們經(jīng)常local m = require "mdname",實(shí)際上是將生成的表進(jìn)行了重命名,但是本質(zhì)上還是mdname這個(gè)表。
pa.lua中的return M我們沒有顯示聲明,由package.loaded[modulename]來代替,通過require實(shí)現(xiàn)機(jī)制可以看到,這時(shí)候返回值應(yīng)該是true。
三、環(huán)境
lua用_G一張表保存了全局?jǐn)?shù)據(jù)(變量,函數(shù)和表等)。
如上分析,我們定義一個(gè)module,如果不加local,則它是一個(gè)注冊(cè)在全局下的表。我們通過加local避免了它在污染全局表空間,只在本文件生效。如果我們沒有將其注冊(cè)到_G下,在其他文件是無法直接通過他的原始名字來訪問的。不便利的地方,每個(gè)函數(shù)前面都要帶M,M的下的函數(shù)相互訪問也要帶M頭。
解決方法:通過setfenv
local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M
setfenv(1, M)
后續(xù)的函數(shù)直接定義名字,因?yàn)樗麄兊沫h(huán)境空間已經(jīng)由_G改為了M。
如果要使用全局函數(shù),則可以本地額外增加一條local _G = _G或者setmetatable(M, {__index = G})。
更好的方法是在setfenv之前將需要的函數(shù)都保存起來,local sqrt = math.sqrt
四、module函數(shù)
local M = {}
_G[modname] = M
package.loaded[modname] = M
<set for external access: eg setmetatable(M, {__index = _G})>
setfenv(1, M)
等同于module(modname)。
默認(rèn)情況下,module不提供外部訪問,如果要訪問外部變量,兩種方法:
1.在聲明module之前,local 變量 = 外部變量
2.使用module(modname, package.seeall), 等價(jià)于setmetatable(M, __index = _G)
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
本文標(biāo)題:luarequire與module-創(chuàng)新互聯(lián)
地址分享:http://m.rwnh.cn/article36/cciopg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、營(yíng)銷型網(wǎng)站建設(shè)、Google、關(guān)鍵詞優(yōu)化、App設(shè)計(jì)、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容