在lua中,加載代碼文件,通常會見到require、dofile、loadfile等函數,分析如下:
1、require
在加載一個.lua文件時,require會先在package.loaded中查找此模塊是否存在,如果存在,直接返回模塊。
如果不存在,則加載模塊文件。示例如下:
- --test1.lua
- function Fac(n)
- if n <= 1 then
- return n
- end
- return n * Fac(n-1)
- end
- --test2.lua
- a = require("test1")
- print("require res="..tostring(a))
- print("5!="..Fac(5))
- require res=true
- 5!=120
2、dofile和loadfile
dofile:讀入代碼文件並編譯執行。每調用dofile一次,都會重新編譯執行一次。
loadfile:編譯代碼,將整個模塊文件當成一個函數返回,但是不執行代碼。
dofile是對loadfile的一次包裝
示例代碼:將test2.lua代碼修改成:
- --test2.lua
- a = loadfile("test1.lua")
- print("loadfile res="..tostring(a))
- print("5!="..Fac(5))
這就說明,代碼確實沒有運行,而且loadfile是返回了一個函數
dofile測試如下:
- --test2.lua
- a = dofile("test1.lua")
- print("dofile res="..tostring(a))
- print("5!="..Fac(5))
那麼,在lua中,如何利用這些函數,編寫一個模塊呢?
如果你只是需要編寫一個函數庫,比如所有對數據運算的操作,math_func.lua,可能的功能函數如下:
- --math_func.lua
- function Sum(a, b)
- return a + b
- end
- function Fac(n)
- if n <= 1 then
- return n
- end
- return n * Fac(n-1)
- end
這樣的做法是不提倡的,原因如下:
1:會引起命名混亂,a.lua裏面有個Sum,b.lua裏面也有個Sum,最後就會出現衝突了,函數會被覆蓋
2:調用方無法識別
所以,我比較喜歡的做法是:
- --math_func.lua
- math_func = {}
- function math_func.Sum(a, b)
- return a + b
- end
- function math_func.Fac(n)
- if n <= 1 then
- return n
- end
- return n * math_func.Fac(n-1)
- end
- return math_func
- --test.lua
- MATH_FUNC = require("test1")
- print("11 + 22 = "..tostring(MATH_FUNC.Sum(11,22)))
- print("5!="..MATH_FUNC.Fac(5))
避免了名字空間問題,也方便了不少,同時也不用擔心重複加載