Lua教程(十一) 模組與包詳解

2022-09-21 02:21:08 字數 2646 閱讀 8611

從lua 5.1程式設計客棧開始,我們可以使用require和module函式來獲取和建立lua中的模組。從使用者的角度來看,乙個模組就是乙個程式庫,可以通過require來載入,之後便得到乙個型別為table的全域性變數。此時的table就像名字空間一樣,可以訪問其中的函式和常量,如:

複製** **如下:

require "mod"

mod.foo()

local m2 = require "mod2"

local f = mod2.foo

f() 

1. require函式:

require函式的呼叫形式為require yteprzrldm"模組名"。該呼叫會返回乙個由模組函式組成的table,並且還會定義乙個包含該table的全域性變數。在使用lua中的標準庫時可以不用顯示的呼叫require,因為lua已經預先載入了他們。

require函式在搜素載入模組時,有一套自定義的模式,如:

複製** **如下:

?;?.lua;c:/windows/?;/usr/local/lua/?/?.lua

在上面的模式中,只有問號(?)和分號(;)是模式字元,分別表示require函式的引數(模組名)和模式間的分隔符。如:呼叫require "sql",將會開啟以下的檔案:

複製** **如下:

sqlsql.lua

c:/windows/sql

/usr/local/lua/sql/sql.lua

lua將require搜尋的模式字串放在變數package.path中。當lua啟動後,便以環境變數lua_path的值來初始化這個變數。如果沒有找到該環境變數,則使用乙個編譯時定義的預設路徑來初始化。如果require無法找到與模組名相符的lua檔案,就會找c程式庫。c程式庫的搜尋模式存放在變數package.cpath中。而這個變數則是通過環境變數lua_cpath來初始化的。

2. 編寫模組的基本方法:    見如下**和關鍵性注釋:

複製** **如下:

--將模組名設定為require的引數,這樣今後重新命名模組時,只需重新命名檔名即可。

local modname = ...

local m = {}

_g[modname] = m

m.i =   --定義乙個模組內的常量。

function m.new(r,i) return end

function m.add(c1,c2)

return m.new(c1.r + c2.r,c1.i + c2.i)

endfunction m.sub(c1,c2)

return m.new(c1.r - c2.r,c1.i - c2.i)

end--返回和模組對應的table。

return m

3. 使用環境:

仔細閱讀上例中的**,我們可以發現一些細節上問題。比如模組內函式之間的呼叫仍然要保留模組名的限定符,如果是私有變數還需要加local關鍵字,同時不能加模組名限定符。如果需要將私有改為公有,或者反之,都需要一定的修改。那又該如何規避這些問題呢?我們可以通過lua的函式「全域性環境」來有效的解決這些問題。見如下修改的**和關鍵性注釋:

複製** **如下:

--模組設定和初始化。這一點和上例一致。

local modname = ...

local m = {}

_g[modname] = m

--宣告這個模組將會用到的全域性函式,因為在setfenv之後將無法再訪問他們,

--因此需要在設定之前先用本地變數獲取。

local sqrt = mat.sqrt

local io = io

--在這句話之後就不再需要外部訪問了。

setfenv(1,m)

--後面的函式和常量定義都無需模組限定符了。

i =

function new(r,i) return end

function add(c1,c2)

return new(c1.r + c2.r,c1.i + c2.i)

end 

function sub(c1,c2)

return new(c1.r - c2.r,c1.i - c2.i)

end--返回和模組對應的table。

return m

4. module函式:

在lua 5.1中,我們可以用module(...)函式來代替以下**,如:

複製** **如下:

local modname = ...

loca程式設計客棧l m = {}

_g[modname] = m

package.load = m

--[[

和普通lua程式塊一樣宣告外部函式。

--]]

setfenv程式設計客棧(1,m)

由於在預設情況下,module不提供外部訪問,必須在呼叫它之前,為需要訪問的外部函式或模組宣告適當的區域性變數。然後lua提供了一種更為方便的實現方式,即在呼叫module函式時,多傳入乙個package.seeall的引數,如:

複製** **如下:

module(...,package.seeall)

注意:5.2已經不支援module了,去看看lua官網的文件,沒有這個函式了,我用package.loaded.module_name = _env來建立模組

本文位址:

lua菜鳥教程 Lua 模組與包

lua 模組與包 模組類似於乙個封裝庫,從 lua 5.1 開始,lua 加入了標準的模組管理機制,可以把一些公用的 放在乙個檔案裡,以 api 介面的形式在其他地方呼叫,有利於 的重用和降低 耦合度。lua 的模組是由變數 函式等已知元素組成的 table,因此建立乙個模組很簡單,就是建立乙個 t...

Lua 模組與包

模組類似於乙個封裝庫,從 lua 5.1 開始,lua 加入了標準的模組管理機制,可以把一些公用的 放在乙個檔案裡,以 api 介面的形式在其他地方呼叫,有利於 的重用和降低 耦合度。lua 的模組是由變數 函式等已知元素組成的 table,因此建立乙個模組很簡單,就是建立乙個 table,然後把需...

Lua 模組與包

模組類似於乙個封裝庫,從lua 5.1開始,lua加入了標準的模組管理機制,可以把一些公用的 放在乙個檔案裡,以api介面的形式在其他地方呼叫,有利於 的重用和降低 耦合度。lua的模組是由變數 函式等已知元素組成的table,因此建立乙個模組很簡單,就是建立乙個table,然後把需要匯出的常量 函...