在Lua中创建一个模块最简单的方法是:创建一个table。
并将所有需要导出的函数放入其中,最后返回这个table。
下例中的inv声明为程序块的局部变量,就是将其定义成一个私有的名称:
local M = {} function M.new(r,i) return {r = r,i=i} end --defines constant 'i' M.i = M.new(0,1) function M.add(c1,c2) return M.new(c1.r + c2.r,c1.i + c2.i) end function M.sub(c1,c2) return M.new(c1.r - c2.r,c1.i - c2.i) end function M.mul(c1,c2) return M.new(c1.r*c2.r - c1.i*c2.i, c1.r * c2.i + c1.i * c2.r) end local function inv(c) local n = c.r^2 + c.i^2 return M.new(c.r/n,-c.i/n) end function M.div(c1,c2) return M.mul(c1,inv(c2)) end function M.tostring(c) return "(" .. c.r .. "," .. c.i .. ")" end
return M
有的人不喜欢最后的return语句,可以通过下面的方法消除它:
local M = {} package.loaded[...] = M < as before >
require调用加载器时,会把模块名作为第一个参数传递给它。因此上面的"..."表达式就是模块名。
通过这样的赋值后,就不需要在模块结尾返回M了,如果一个模块无返回值,require就会返回package.loaded[modname]的当前值(如果不为nil)。
不过写return语句,会显得更简洁一些。
另一种写模块的方式是在模块中把所有函数定义为局部变量,最后在返回的时候建立table。
local function new(r,i) return {r = r , i = i } end -- defines constant 'i' local i = complex.new(0,1) < other functions follow the same pattern > return { new = new, i = i, add = add, sub = sub, mul = mul, div = div, tostring = tostring, }
优点:不需要在每次调用函数时用M去调用;有一个清晰的导出列表;在模块里使用内部函数和外部函数都是一样的调用方法。
缺点:写在文件的最后不利于快速阅读代码;导出列表显得有点多余,必须写两次名字;
不过使用第二种方法,还有一个好处是可以让函数在模块内外有不同的名字。
不管用哪种方式,只要能用标准的方法调用就行。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》