亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發(fā) > 綜合 > 正文

Lua中模塊以及實(shí)現(xiàn)方法指南

2024-07-21 23:04:26
字體:
供稿:網(wǎng)友

從使用的角度來看,一個(gè)模塊就是一個(gè)程序庫,可以通過Lua自身提供的require來加載。然后便得到一個(gè)全局變量,表示一個(gè)table。這個(gè)table就是像一個(gè)名字空間,其內(nèi)容就是模塊導(dǎo)出的所有東西,例如函數(shù)和常量。簡單的說,Lua中的模塊就是一個(gè)table,table中可以包括任何東西。本文首先詳細(xì)介紹模塊相關(guān)的require函數(shù),包括該函數(shù)的執(zhí)行流程以及查找模塊的路徑,然后介紹了實(shí)現(xiàn)模塊的三種方法,并給出相應(yīng)的優(yōu)缺點(diǎn)。

 require函數(shù)

     該函數(shù)用來加載一個(gè)模塊,即按指定的路徑和傳入的參數(shù),查找要加載的模塊。函數(shù)原型如下:

      require (modname)

      該函數(shù)的執(zhí)行流程如下:

      I、查找表package.loaded,看modname是否已經(jīng)加載過了。若是,則require函數(shù)直接返回package.loaded[modname],否則繼續(xù)執(zhí)行,尋找模塊的加載器(loader)。

      II、為了尋找加載器,require使用了數(shù)組package.searchers(Lua 5.2引入的,在之前的版本叫做package.loaders,實(shí)質(zhì)兩者只是名字不同而已),數(shù)組中每個(gè)元素是一個(gè)函數(shù)。

     第一個(gè)函數(shù)用來是搜索表package.preload,若存在,則返回相應(yīng)的加載器。

     第二個(gè)函數(shù)是用來獲取Lua模塊的加載器,其搜索路徑存儲(chǔ)在package.path中,它是一個(gè)字符串,比如:

 

復(fù)制代碼 代碼如下:

/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua;/usr/local/lib/lua/5.2/?/init.lua;./?.lua 

 

會(huì)用模塊名來替換每個(gè)”?”,然后根據(jù)替換的結(jié)果來檢測是否存在這樣的一個(gè)文件。這個(gè)工作是通過函數(shù)package.searchpath來做的。package.searchpath函數(shù)原型如下:
      package.searchpath (name, path [, sep [, rep]])

參數(shù)path是要查找的字符串,用分號(hào)隔開;name是要查找的文件;參數(shù)sep(默認(rèn)值是”.”)可用于name中,在查找過程中用rep(默認(rèn)值是系統(tǒng)目錄的分隔符)替換。比如path是

 

復(fù)制代碼 代碼如下:

"./?.lua;./?.lc;/usr/local/?/init.lua"

 

要查找foo.a,則會(huì)嘗試查找文件

 

復(fù)制代碼 代碼如下:

./foo/a.lua, ./foo/a.lc, 和/usr/local/foo/a/init.lua 

 

也就是說Lua支持具有層級(jí)性的模塊名。
      第三個(gè)函數(shù)是用來獲取C模塊的加載器,其搜索路徑存儲(chǔ)在package.cpath中,它也是一個(gè)字符串,比如:

 

復(fù)制代碼 代碼如下:

/usr/local/lib/lua/5.2/?.so;/usr/local/lib/lua/5.2/loadall.so;./?.so 

 

同樣會(huì)用模塊名來替換每個(gè)”?”,然后根據(jù)替換的結(jié)果來檢測是否存在這樣的一個(gè)文件。這個(gè)工作也是通過函數(shù)package.searchpath來做的。
     第四個(gè)函數(shù)是用all-in-one 加載器,使用這個(gè)功能,可以使得一個(gè)包里面包含多個(gè)C子模塊。除了第一個(gè)外,其他三個(gè)除了返回加載器外,還會(huì)返回找到的文件名作為額外的值。

      III、找到加載器后,require將用兩個(gè)參數(shù)調(diào)用這個(gè)加載器,一個(gè)是傳入的參數(shù)modname,另外一個(gè)是返回的額外值。如加載器返回一個(gè)不是nil的值,則把這個(gè)值賦值給package.loaded[modname]。如果加載返回返回一個(gè)nil并且加載器執(zhí)行完后package.loaded[modname]還為空,則把package.loaded[modname]賦值為true。不管那種情況,require都會(huì)返回package.loaded[modname]。如果在這個(gè)過程有任務(wù)錯(cuò)誤,require函數(shù)就產(chǎn)生一個(gè)錯(cuò)誤給調(diào)用者。

     最后關(guān)于require函數(shù),值得注意的幾點(diǎn)是:

     I、如果require找到的是一個(gè)lua文件,則通過loadfile來加載代碼,如果找到的是一個(gè)C程序庫,就通過loadlib來加載。注意,loadfile和loadlib都實(shí)質(zhì)上加載代碼,并沒有運(yùn)行他們。為了運(yùn)行他們,require會(huì)用模塊名作為參數(shù)來調(diào)用這些代碼。

     II、若要強(qiáng)制使require對(duì)同一庫加載兩次,可以簡單刪除package.loaded中的模塊條目,即賦值相應(yīng)的條目為nil。

     III、通過上面的加載過程分析知道,要加載自己的lua文件或C庫,可以通過修改package.path或package.cpath的值,把要搜索的路徑加載進(jìn)去。

      IV、也可以定義自己的加載函數(shù)(除了已有的loadlib和loadfile等),比如加載ZIP文件,甚至從web上下載一個(gè)文件。

編寫模塊的方法

     方法一:對(duì)于Lua5.0和5.1來說,編寫模塊最簡單的方法是使用Lua自身提供的module函數(shù)(注意在Lua 5.2中被刪除了),比如要編寫一個(gè)模塊foo,模塊文件foo_file.lua如下:

 

復(fù)制代碼 代碼如下:

module("foo", package.seeall) 
function test() 
end 

 

則在其他文件要使用這個(gè)模塊,方式如下:

 

復(fù)制代碼 代碼如下:

require(“foo_file.lua”) 
foo.test() 

 

并且執(zhí)行require后,則會(huì)把模塊foo就是全局環(huán)境的一個(gè)變量了,在其他地方也可以使用。module函數(shù)原型如下:

 

復(fù)制代碼 代碼如下:

module (name [, ···]) 

 

module在創(chuàng)建模塊table之前,會(huì)先檢查package.loaded是否已包括了這個(gè)模塊,或者是否已存在與模塊同名的變量。如果由此找到了這個(gè)table,它就會(huì)復(fù)用這個(gè)table做為模塊。也就是說,可以用module來打開一個(gè)已創(chuàng)建的模塊。

對(duì)于module函數(shù)來說,有以下問題,比如在模塊文件module0_test中有:

 

復(fù)制代碼 代碼如下:

module("mymodule", package.seeall)                                                                      
function foo() 
    print("Hello World!") 
end 

 

在另外一個(gè)文件可以這樣使用這個(gè)模塊:

 

復(fù)制代碼 代碼如下:

require "module0_test" 
mymodule.foo()             --Hello World! 
mymodule.print("example")  --example 

 

對(duì)于第二個(gè)調(diào)用不是報(bào)錯(cuò)的,并且是非常奇怪的,這時(shí)因?yàn)閙odule機(jī)制是在模塊中找不的成員,則去_G全局變量找,實(shí)現(xiàn)方式類似如下:

do   local globaltbl = _G   local newenv = setmetatable({}, {     __index = function (t, k)       local v = t[k]       if v == nil then return globaltbl[k] end       return v     end,     __newindex = M,   })   if setfenv then     setfenv(1, newenv) -- for 5.1   else     _ENV = newenv -- for 5.2   end end 

在模塊找不到的成員,則到_G中去查找,并且這樣訪問也是非常低效的,因?yàn)橐ㄟ^元表來訪問成員。

 方法二:該方法的基本思想是讓模塊的主程序有一個(gè)獨(dú)占的環(huán)境,這樣所有函數(shù)或變量都共享這個(gè)table,并且所有的全局變量都記錄在這個(gè)table中,當(dāng)然局部變量是不會(huì)的。代碼片段如下:

local modename = ... local M = {} _G[modename] = M package.loaded[modname] = M if setfenv then   setfenv(1, newenv) -- for 5.1 else   _ENV = newenv -- for 5.2 end 

如果這樣實(shí)現(xiàn),在模塊訪問_G中的變量時(shí),需要加上前綴,比如_G.print。為了解決這個(gè)問題,有幾種方法,各有優(yōu)缺點(diǎn):

 I、設(shè)置M的元表,即setmetable(M, {__index = _G})這樣做后,訪問全局變量,都要通過元表,開銷比較大。

 II、設(shè)置local _G = _G,這樣做后,訪問全局變量仍然要加上前綴,但速度更快。

 III、把模塊需要的全局變量都設(shè)置為局部變量,比如local io = io。這樣做會(huì)比較繁瑣,但是速度最快。

方法三:同樣是使用環(huán)境的概念。比如模塊文件如下:

 

復(fù)制代碼 代碼如下:

function foo()                                                                                          
    print("Hello World!")                                                                               
end 

 

為了使用它,方法如下:

local function Import(filename)                                       f = loadfile(filename)                                          local M = {}                                               setmetatable(M, {__index = _G})                                     setfenv(f,M)()   return M end  local FOO = Import("module2_test.lua")  FOO.foo() --output “Hello World!” 

用這種方法,只需調(diào)用Import方法,其返回值就是模塊,該方法把模塊相關(guān)訪問工作,放在使用的模塊的地方了。

以上所述就是本文的全部內(nèi)容了,希望能夠?qū)Υ蠹覍W(xué)習(xí)lua有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
日韩欧美在线视频观看| 欧美亚洲免费电影| 欧美大片一区| 欧美18一14sex性处hd| 欧美在线导航| xfplay5566色资源网站| 91精彩视频在线观看| 三级黄视频在线观看| 亚洲国产成人精品无码区99| 欧美日韩在线播放一区二区| 日本中文字幕网| 成人动漫在线免费观看| 日本一区视频在线观看免费| 精品卡一卡二卡三卡四在线| 欧洲一区精品| 蜜桃av综合| 欧美aaaaa成人免费观看视频| 韩国精品久久久999| 亚洲欧美制服中文字幕| 韩国日本不卡在线| 国内不卡的一区二区三区中文字幕| 黄色视屏在线免费观看| www视频在线看| 国产成人综合精品三级| 成人在线观看小视频| 欧亚乱熟女一区二区在线| 国产叼嘿网站免费观看不用充会员| 中文字幕av观看| 一区二区在线免费视频| 性生交免费视频| 农村妇女精品一区二区| 色国产精品一区在线观看| 国产人妻精品一区二区三区| 激情内射人妻1区2区3区| 欧亚一区二区三区| 99精品在免费线中文字幕网站一区| 欧美国产日韩中文字幕在线| 免费看成年视频网页| 国产一区观看| 久久日免费视频| 激情五月综合| 一级片免费看| 欧美色综合网| 91亚洲国产高清| 激情综合五月天| 日韩精彩视频在线观看| 黄色的网站在线观看| 亚洲网站视频福利| 三级黄色录像视频| 爽爽淫人综合网网站| 91尤物国产福利在线观看| 色天天色综合| 亚洲人精品午夜在线观看| 亚洲色图美腿丝袜| 中文字幕一区不卡| 成人黄动漫网站| 国产成人av电影在线播放| 亚洲在线日韩| 91久久久久久久一区二区| 国产叼嘿网站免费观看不用充会员| 亚洲综合色av| 欧美日韩激情在线观看| 亚洲男人天堂古典| 一区二区三区三区在线| 亚洲在线第一页| 精品一区二区三区亚洲| 精品视频一区二区在线| 91在线视频国产| 欧美精品在线极品| 最新国产の精品合集bt伙计| 欧美黑人双插| 国产视频精选在线| 国产日本亚洲高清| 91theporn国产在线观看| 久久久精品五月天| 久久综合久久八八| 国产精品日日夜夜| 久久亚洲人体| 亚洲欧美一区二区精品久久久| 26uuu亚洲综合色| 日本在线播放视频| 欧美一区日本一区韩国一区| 久久久免费在线观看| 欧美一区二区三区久久精品| 一级毛片免费视频| 日本成人伦理电影| 1pon在线| 无遮挡亚洲一区| 男女羞羞视频教学| eeuss影院www在线观看手机| 国外成人在线播放| 欧美一区二区三区激情视频| 黄色精品视频网站| 中文精品在线| 天天综合色天天综合色hd| 无码任你躁久久久久久老妇| 成人激情黄色网| 999久久久久久久久6666| 亚洲码无人客一区二区三区| 午夜精品999| 国产精品综合在线| 69久久99精品久久久久婷婷| 久草网在线视频| 亚洲欧美日本免费| 亚洲色成人www永久在线观看| 免费a在线观看| 精品国产一区二区三区麻豆小说| 天天插天天射天天干| 污污的网站在线免费观看| eeuss影院www天堂免费| 青青免费在线视频| 欧美激情第六页| www.国产福利| 天天看片天天操| 久久影院电视剧免费观看| 岛国视频一区| 国产伦精品一区二区三区免费视频| 一区二区三区视频在线免费观看| 日本va欧美va精品| 久久久免费精品视频| 国产精品久久久久久精| 国产一级二级在线| 黄色三及免费看| 亚洲国产视频在线观看| 国产精品毛片一区二区三区四区| 热久久这里只有| 中文成人综合网| 亚洲激情自拍视频| 99热国产免费| 久久伊人色综合| 视频一区二区三区四区五区| 亚洲人妖在线| 日本一级黄色大片| 少妇视频在线| ,亚洲人成毛片在线播放| 91在线看黄| 视频在线99re| 97精品国产97久久久久久春色| 欧美激情一级精品国产| 91视频com| 99v久久综合狠狠综合久久| 中国女人真人一级毛片| 国内老熟妇对白hdxxxx| 激情视频一区二区| 成人情趣视频网站| 99久久久久免费精品国产| 林心如三级全黄裸体| 精品理论电影在线| 欧美天天在线| 导航福利在线| 丰满大乳国产精品| 老司机午夜精品视频在线观看| 日本一区二区三区视频视频| www久久com| 秋霞成人午夜鲁丝一区二区三区| 国产精品午夜久久| www亚洲欧美| а√天堂资源国产精品| 玛雅亚洲电影| 国产精品成人观看视频国产奇米| 熟女少妇在线视频播放| 久久男人中文字幕资源站| 免费91麻豆精品国产自产在线观看| 亚洲午夜精品久久久中文影院av| 国内视频在线精品| 亚洲欧美成aⅴ人在线观看| 国产 中文 字幕 日韩 在线| 亚洲福利在线视频| 99久久精品免费看国产四区| 日韩美女视频免费在线观看| 69sex久久精品国产麻豆| 九色porny视频在线观看| 欧亚精品一区| 综合欧美国产视频二区| 337p粉嫩大胆噜噜噜噜噜91av| 欧美一级片黄色| 最近免费中文字幕mv视频| 欧美激情在线观看| 久久99精品国产99久久| 欧美aaa视频| 精品剧情在线观看| 99视频一区二区三区| 久久久久一区二区| 亚洲欧美国内爽妇网| 国产精品久久久久久久7电影| 日韩午夜在线电影| 午夜在线免费视频| 动漫3d精品一区二区三区| 中文字幕一区二区三区四区| 日韩欧美高清一区二区三区| 翔田千里亚洲一二三区| 激情六月丁香婷婷| 麻豆电影在线| 精品国产青草久久久久福利| 东京热加勒比无码少妇| 欧美日韩一区二区三区电影| 天堂在线免费观看视频| 欧美成人高潮一二区在线看| 国产欧美日韩综合精品一区二区| www.在线欧美| 国产不卡精品视频| 综合婷婷亚洲小说| 亚洲毛片在线免费| 亚洲综合色婷婷| 国产米奇在线777精品观看| 四虎影视永久免费在线观看一区二区三区| 在线观看黄网站| 亚洲精品不卡在线| 3p视频在线观看| 亚洲成人一区| 黄网站在线免费看| 妺妺窝人体色www在线小说| 成人午夜大片免费观看| 中文在线最新版天堂| 精品国产乱码久久久久久蜜柚| 欧美美女啪啪| 国产cdts系列另类在线观看| 国产区精品在线观看| 四虎影院免费在线| 51漫画成人app入口| 亚洲成人免费| sese综合| 一本加勒比波多野结衣| 7878视频在线观看| 夜夜操夜夜操| 风流少妇一区二区三区91| 国产在线视频在线观看| 9i看片成人免费高清| 国产成人涩涩涩视频在线观看| caoliu在线| 国产精品自在线拍| 久久青青色综合| 日韩视频免费观看高清在线视频| 18成人免费观看视频漫画| 人xxxx性xxxxx欧美| 日本sm极度另类视频| 久久久久久无码午夜精品直播| 国产精品欧美一区二区三区不卡| 久久er这里只有精品| 91嫩草|国产丨精品入口| 欧美成人毛片| 日韩一区二区三区在线| 黄色工厂这里只有精品| 国产蜜臀在线| 亚洲在线播放电影| 一区二区三区美女| 一区2区3区在线看| 正在播放日韩欧美一页| 日本高清久久一区二区三区| 3d黄动漫网站| 国产精品久久久午夜夜伦鲁鲁| 国产网站av| 最近免费中文字幕大全免费第三页| 亚洲www色| 先锋影音在av资源看片| 国产欧美一区二区三区在线看蜜臀| 欧美一区二区视频观看视频| 欧美乱人伦中文字幕在线| 免费人成自慰网站| 国产精品亚洲视频在线观看| 91丨九色丨尤物| 91中文字幕| 福利一区在线观看| 久久久免费视频网站| 国产性猛交普通话对白| 在线观看av不卡| 国产欧美视频一区二区三区| 亚洲男人天堂色| 精品国产乱码久久久久久鸭王1| 国产高潮流白浆喷水视频| 波多野结衣加勒比| 美女视频在线免费| 日本一区影院| 欧美黄色免费视频| 亚洲精品免费网站| 欧美激情极品视频| 野外性xxxxfreexxxxx欧美| 91国产精品91| 冲田杏梨av在线| 一区视频在线播放| 在线满18网站观看视频| 欧美a免费在线| 人妻无码一区二区三区四区| 日本不卡视频在线| 在线精品高清中文字幕| 欧洲精品视频在线观看| 国产精品蜜芽在线观看| 日韩小视频在线| 国产一区二区三区不卡免费观看| 三级全黄做爰视频| 一区二区三区国产盗摄| 国产露脸无套对白在线播放| 亚洲精品91| 秋霞一区二区三区| 男人本色网站| 免费cad大片在线观看| 在线免费观看的av网站| 1024精品一区二区三区| 亚洲午夜久久久久久久久电影网| 草民午夜欧美限制a级福利片| 国产欧美日韩一区二区三区四区| 黄大色黄女片18免费| 最新国产麻豆精品| 久久无码专区国产精品s| 亚洲成人人体| 精品久久久久久久久久岛国gif| 国产欧美一区二区精品忘忧草| 欧美日韩在线免费观看视频| 粉嫩aⅴ一区二区三区| 亚洲欧美日韩另类| 亚洲成人av片在线观看| 久久久久久久久久久影院| 午夜影院一区| 韩国一区二区三区四区| 综合区小说区图片区在线一区| 亚洲香肠在线观看| 69**夜色精品国产69乱| blackedav金发美女大战黑人| 日韩欧美一区二区三区久久| 久久国产在线视频| 精品视频1区2区| 欧美日韩激情电影| 国产在线观看a视频| 亚洲美女黄色| 精品少妇一区二区三区在线| 久久久综合九色合综国产精品| 国产肥白大熟妇bbbb视频| 男人揉女人奶房视频60分|