Step By Step Lua模組與包

2021-09-01 17:23:57 字數 2615 閱讀 1500

從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 "模組名"。該呼叫會返回乙個由模組函式組成的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)

endfunction 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 = ...

local m = {}

_g[modname] = m

package.loaded[modname] = m

--[[

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

--]]

setfenv(1,m)

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

module(...,package.seeall)

原文:

Step By Step Lua呼叫C函式

lua可以呼叫c函式的能力將極大的提高lua的可擴充套件性和可用性。對於有些和作業系統相關的功能,或者是對效率要求較高的模組,我們完全可以通過c函式來實現,之後再通過lua呼叫指定的c函式。對於那些可被lua呼叫的c函式而言,其介面必須遵循lua要求的形式,即typedef int lua cfun...

任務模組 報告模組 日誌模組

需求背景 報告模組 怎麼來處理這個報告的問題,報告是非常重要的一塊,1,可以看到每一次執行的情況,多少通過了,多少失敗了 2,可以看到執行的日誌,每一步的日誌,失敗了,我要知道失敗在 了,3,每次都要有報告 業務設計 1,任務列表,任務名稱,檢視任務詳情,報告列表,執行的功能,2,任務詳情,每乙個用...

模組之shutil模組模組詳解

shutil模組是高階的 檔案 資料夾 壓縮包 處理模組 shutil.copyfileobj fsrc,fdst length 將檔案內容拷貝到另乙個檔案中 shutil.copyfile src,dst 拷貝檔案 shutil.copymode src,dst 僅拷貝許可權。內容 組 使用者均不...