舊式的模塊定義方式是通過 module("filename"[,package.seeall])*
來顯式聲明一個包,現(xiàn)在官方不推薦再使用這種方式。這種方式將會返回一個由 filename
模塊函數(shù)組成的 table
,并且還會定義一個包含該 table
的全局變量。
module("filename", package.seeall)
這種寫法是不提倡的,官方給出了兩點原因:
package.seeall
這種方式破壞了模塊的高內(nèi)聚,原本引入 "filename" 模塊只想調(diào)用它的 foobar() 函數(shù),但是它卻可以讀寫全局屬性,例如 "filename.os"
。module
函數(shù)壓棧操作引發(fā)的副作用,污染了全局環(huán)境變量。例如 module("filename")
會創(chuàng)建一個 filename
的 table
,并將這個 table
注入全局環(huán)境變量中,這樣使得沒有引用它的文件也能調(diào)用 filename
模塊的方法。比較推薦的模塊定義方法是:
-- square.lua 長方形模塊
local _M = {} -- 局部的變量
_M._VERSION = '1.0' -- 模塊版本
local mt = { __index = _M }
function _M.new(self, width, height)
return setmetatable({ width=width, height=height }, mt)
end
function _M.get_square(self)
return self.width * self.height
end
function _M.get_circumference(self)
return (self.width + self.height) * 2
end
return _M
引用示例代碼:
local square = require "square"
local s1 = square:new(1, 2)
print(s1:get_square()) --output: 2
print(s1:get_circumference()) --output: 6
另一個跟 Lua 的 module 模塊相關需要注意的點是,當 lua_code_cache on 開啟時,require 加載的模塊是會被緩存下來的,這樣我們的模塊就會以最高效的方式運行,直到被顯式地調(diào)用如下語句(這里有點像模塊卸載):
package.loaded["square"] = nil
我們可以利用這個特性代碼來做一些高階玩法,比如代碼熱更新等。