Chapter 15_2 编写模块的基本方法

  在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 》

 

posted @ 2016-09-12 19:03  daiker  阅读(148)  评论(0编辑  收藏  举报