【Lua學習筆記7】Lua中的模塊加載

require關鍵字

lua中使用require來加載對應的模塊。html

基本用法:

好比我有個一個文件test.lua,內容以下:node

test = {}

test.fun1 = function() return 1 end

return test;
複製代碼

而後在main.lua中使用require引入:shell

require('test')
print(test.fun1()) --> 1
複製代碼

加載過程

跟node加載模塊同樣,lua中的模塊加載過程也須要一個查找過程。在使用require加載lua模塊的時候,lua首先會查看package.loaded表中是否存在該模塊,若是存在,說明該模塊以前已經加載過了,那麼久直接返回這個表中的對應模塊。緩存

其實就是模塊的全局緩存的效果,保證每一個模塊只需加載一次就夠了。函數

若是package.loaded表中沒有該模塊,則會先針對這個模塊尋找一個loader,這個loader工做你懂得,就是用來加載這個模塊的。ui

因此如今的流程就是,lua

    1. require(moduleName)
    1. 看下package.loaded[moduleName]有沒有值,沒有走第三步
    1. 看下package.preload[moduleName]有沒有值,有就返回,沒有走第四步
    1. 使用packege.path中指定的路徑去搜索loader,若是失敗走第五步
    1. 使用packge.cpath中指定的路徑去搜索C loader,若是仍是失敗了,則走第六步
    1. 使用package.searchers中配置的loader來加載模塊。

若是以上的流程中查找到了模塊的loader,則require會調用這個加載程序,而且將模塊名稱和一個額外的參數傳遞給該loader(若是這個loader來自一個文件,則該參數的值爲文件名)。若是loader沒有給package.loaded添加任何值並且也沒有返回任何的非零值,則講package.loaded[moduleName]設置爲true。而後require會返回package.loaded[moduleName]給到調用方。spa

在上面的加載過程當中,若是出現了失敗或者錯誤,require就會拋出一個錯誤。code

package.preload

用來存儲一些特殊的模塊,個人理解就是用來存儲一些自定義的loader的。htm

package.path

這個配置用來告訴lua去哪裏查找模塊的loader。 在啓動時,Lua使用環境變量LUA_PATH_5_3或環境變量LUA_PATH的值或使用luaconf.h中定義的默認路徑初始化此變量(若是未定義這些環境變量)。任何 」;;」在環境變量的值中由默認路徑替換。

package.cpath

跟path差很少,主要用來加載C語言的庫,這個就不說了。

package.searchers

package.searchers是lua用來控制如何加載以及去哪裏加載對應模塊的表。這個表裏面的每個屬性都是一個查找函數,lua會按升序排序,而後根據這個順序來調用查找函數,將require函數傳遞過來的參數給到查找函數,而後去執行對應的查找。

lua在初始化package.searchers表的時候,會添加如下4個查找函數:

    1. 第一個查找函數只在package.preload表中查找loader
    1. 第二個查找函數,按package.path中的配置路徑來查找loader,匹配過程用package.searchpath中的配置說明來匹配
    1. 第三個是加載C語言庫的,跟path的同樣
    1. 第四個也是用來加載C語言庫的,就不說了,有須要的查看這裏的官方文檔

package.searchpath

package.searchpath (name, path [, sep [, rep]])
複製代碼
  • name: 搜索的名稱
  • path: 指定的搜索路徑
  • sep:名稱中的分隔符,默認是一個點(.)
  • rep: 在路徑中的佔位符,最終會被實際的名稱給替換,默認爲?

舉個例子: 若是path中配置了下面這個路徑:

"./?.lua;./?.lc;/usr/local/?/init.lua"
複製代碼

而後須要查找一個foo.a模塊的話,則會去尋找這些路徑的文件:

./foo/a.lua
./foo/a.lc
/usr/local/foo/a/init.lua
複製代碼

返回第一個查找的結果,若是沒有找到,則返回nil和錯誤信息(嘗試打開的全部文件)。

相關文章
相關標籤/搜索