婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Lua中模塊以及實現方法指南

Lua中模塊以及實現方法指南

熱門標簽:新岸線智能電銷機器人 清朝地圖標注哈爾濱 漳州智云呼電話機器人 武漢外呼防封系統多少錢 個人怎么在地圖標注需要的店鋪 百度地圖標注早餐區域 冀州市地圖標注 地圖標注大廈 怎么去除地圖標注

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

 require函數

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

      require (modname)

      該函數的執行流程如下:

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

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

     第一個函數用來是搜索表package.preload,若存在,則返回相應的加載器。

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

復制代碼 代碼如下:

/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 

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

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

復制代碼 代碼如下:

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

要查找foo.a,則會嘗試查找文件

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

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

      III、找到加載器后,require將用兩個參數調用這個加載器,一個是傳入的參數modname,另外一個是返回的額外值。如加載器返回一個不是nil的值,則把這個值賦值給package.loaded[modname]。如果加載返回返回一個nil并且加載器執行完后package.loaded[modname]還為空,則把package.loaded[modname]賦值為true。不管那種情況,require都會返回package.loaded[modname]。如果在這個過程有任務錯誤,require函數就產生一個錯誤給調用者。

     最后關于require函數,值得注意的幾點是:

     I、如果require找到的是一個lua文件,則通過loadfile來加載代碼,如果找到的是一個C程序庫,就通過loadlib來加載。注意,loadfile和loadlib都實質上加載代碼,并沒有運行他們。為了運行他們,require會用模塊名作為參數來調用這些代碼。

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

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

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

編寫模塊的方法

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

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

并且執行require后,則會把模塊foo就是全局環境的一個變量了,在其他地方也可以使用。module函數原型如下:

復制代碼 代碼如下:

module (name [, ···]) 

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

對于module函數來說,有以下問題,比如在模塊文件module0_test中有:

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

對于第二個調用不是報錯的,并且是非常奇怪的,這時因為module機制是在模塊中找不的成員,則去_G全局變量找,實現方式類似如下:

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中去查找,并且這樣訪問也是非常低效的,因為要通過元表來訪問成員。

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

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 

如果這樣實現,在模塊訪問_G中的變量時,需要加上前綴,比如_G.print。為了解決這個問題,有幾種方法,各有優缺點:

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

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

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

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

復制代碼 代碼如下:

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!” 

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

以上所述就是本文的全部內容了,希望能夠對大家學習lua有所幫助。

您可能感興趣的文章:
  • Lua中的模塊與module函數詳解
  • Lua模塊和模塊載入淺析
  • Lua中的模塊(module)和包(package)詳解
  • Lua極簡入門指南(六):模塊
  • Lua模塊與包學習筆記

標簽:金昌 天門 天門 宣城 臺灣 濰坊 儋州 德宏

巨人網絡通訊聲明:本文標題《Lua中模塊以及實現方法指南》,本文關鍵詞  Lua,中,模塊,以及,實現,方法,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Lua中模塊以及實現方法指南》相關的同類信息!
  • 本頁收集關于Lua中模塊以及實現方法指南的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    91精品国产欧美日韩| 色94色欧美sute亚洲线路二| 国产福利一区在线观看| 3d动漫精品啪啪1区2区免费| 亚洲一线二线三线久久久| 色国产综合视频| 亚洲精品国产成人久久av盗摄| 99久久精品久久久久久清纯| 国产精品久久精品日日| 91蜜桃在线免费视频| 亚洲另类中文字| 91成人在线免费观看| 洋洋成人永久网站入口| 一区二区国产盗摄色噜噜| 91小视频在线免费看| 国产人伦精品一区二区| www.欧美精品一二区| 欧美激情一区二区三区不卡| 福利一区二区在线| 久久久亚洲精品一区二区三区| 亚洲高清免费观看高清完整版在线观看| 韩日av一区二区| 欧美性猛片aaaaaaa做受| 成人国产精品免费观看动漫| 久久久精品免费网站| 一区二区三区四区av| 国产电影一区在线| 欧美日韩精品免费观看视频| 中文字幕不卡一区| 麻豆精品一区二区av白丝在线| 日本三级韩国三级欧美三级| 日本在线观看不卡视频| 在线影院国内精品| 亚洲欧洲日本在线| 国产1区2区3区精品美女| 日韩欧美在线综合网| 亚洲精品视频一区| www.亚洲国产| 亚洲免费av网站| 色婷婷综合久久久久中文| 国产日韩精品一区二区浪潮av| 美国欧美日韩国产在线播放| 久久99精品国产91久久来源| 91欧美一区二区| 国产视频一区二区在线| 亚洲视频免费观看| av福利精品导航| 欧美老年两性高潮| 亚洲第一福利一区| 麻豆国产91在线播放| 亚洲福利一区二区| 欧美精品xxxxbbbb| 久久99精品国产麻豆婷婷| 久久免费美女视频| caoporm超碰国产精品| 一区免费观看视频| 91久久线看在观草草青青| 亚洲国产日韩一区二区| 在线精品视频小说1| 亚洲午夜精品17c| 欧美日韩国产在线观看| 日韩中文字幕一区二区三区| 欧美一区二区三区啪啪| 久久精品国产99久久6| 欧美激情艳妇裸体舞| 色哟哟一区二区在线观看| 亚洲精品视频在线| 亚洲一级不卡视频| www.成人在线| 久久国产免费看| 亚洲国产电影在线观看| 欧洲精品中文字幕| 韩国女主播成人在线| 亚洲欧洲一区二区三区| 欧美一级一区二区| 成人黄色777网| 日韩电影在线一区| 国产精品女同互慰在线看| 欧美艳星brazzers| 久久99国产精品尤物| 亚洲日韩欧美一区二区在线| 欧美三级视频在线观看| 成人永久aaa| 亚洲国产成人av好男人在线观看| 久久综合狠狠综合久久综合88| 91久久精品日日躁夜夜躁欧美| 99国内精品久久| 国产亚洲综合在线| 强制捆绑调教一区二区| 欧美视频中文字幕| 成人黄色小视频在线观看| 欧美一区二区三区在线视频| 国产一区二区三区| 亚洲a一区二区| 777欧美精品| 精品一区二区三区视频| 亚洲免费资源在线播放| 久久蜜臀中文字幕| 69堂成人精品免费视频| 欧美日韩三级一区| 亚洲一级二级三级| 欧美日韩高清一区二区不卡| 色丁香久综合在线久综合在线观看| 亚洲精品免费视频| 中文字幕第一区第二区| 欧美电影免费观看高清完整版| 91官网在线免费观看| 国产一区二区伦理片| 日韩av一二三| 亚洲一卡二卡三卡四卡| 一区二区三区成人| 一区二区三区中文字幕| 欧美伊人久久久久久午夜久久久久| 国产成人综合视频| 亚洲在线一区二区三区| 亚洲色图视频网站| 亚洲欧美一区二区在线观看| 亚洲国产精品99久久久久久久久 | 91丨九色porny丨蝌蚪| 国产盗摄一区二区| 成人综合婷婷国产精品久久 | 欧美自拍偷拍一区| 色综合天天在线| 91麻豆6部合集magnet| 972aa.com艺术欧美| 99精品热视频| 成人h动漫精品| www.亚洲色图.com| 欧美性色欧美a在线播放| 欧美无砖专区一中文字| 欧美一级理论片| 欧美成人三级在线| www国产亚洲精品久久麻豆| 久久夜色精品一区| 国产精品美女视频| 911国产精品| 国产成人亚洲综合a∨婷婷图片| 蓝色福利精品导航| 2020国产精品| 国产精品久久久久久久久快鸭| 亚洲欧洲中文日韩久久av乱码| 午夜激情一区二区三区| 久久精品国产第一区二区三区 | 欧美成人猛片aaaaaaa| 久久精品欧美日韩| 亚洲欧美在线视频观看| 日本不卡一区二区三区| 黄网站免费久久| 99免费精品视频| 欧美日韩高清影院| 亚洲欧洲av另类| 国产精品天天摸av网| 久久女同精品一区二区| 国产精品久久久久三级| 亚洲图片自拍偷拍| 久久国产精品99久久人人澡| 亚洲va欧美va人人爽| 亚洲不卡在线观看| 高清在线不卡av| 在线国产电影不卡| 精品国产乱码91久久久久久网站| 亚洲人快播电影网| 久久国产精品第一页| 欧美日韩精品免费| 亚洲欧美一区二区不卡| 成人黄色a**站在线观看| 精品久久久久久最新网址| 一区二区三区精品视频| 成人美女视频在线观看| 欧美刺激脚交jootjob| 亚洲国产视频a| 一本到不卡精品视频在线观看| 久久久不卡影院| 日韩国产成人精品| 一本一本大道香蕉久在线精品 | 亚洲国产精品一区二区www在线| 日韩精品福利网| 欧美亚洲国产bt| 久久青草欧美一区二区三区| 国产精品久久久久久久裸模 | 日韩av中文在线观看| 色一区在线观看| 《视频一区视频二区| 国产成人精品免费视频网站| 欧美zozo另类异族| 美女在线观看视频一区二区| 555www色欧美视频| 五月婷婷激情综合| 欧美日韩一级黄| 亚洲国产欧美日韩另类综合| 欧美色综合天天久久综合精品| 国产精品久久久久久久久免费樱桃 | 中文字幕高清一区| 国产成人综合自拍| 国产精品视频观看| 99亚偷拍自图区亚洲| 国产精品青草久久| 99久久精品国产导航| 国产精品久线观看视频| 91天堂素人约啪|