lua 模块与环境
编写一个模块的最简单方法:
-- complex.lua
-- 模块实际上是一个表
complex = {}
-- 定义模块函数
function complex.add(c1,c2) ... end
-- 调用模块内部的函数,需要complex.前缀
function complex.callAdd(c1,c2)
complex.add(c1,c2)
end
-- 之前的声明把所有函数都放入complex表中了,最后返回这个表
return complex
调用这个模块时:
-- main.lua
local complex = require("complex")
complex.add(x,y)
上述代码有几点麻烦:
1.在模块内部,一个函数调用另一个函数时,必须加上complex前缀
2.最后必须返回complex这个表
改进的办法:
-- complex.lua
-- 模块实际上是一个表,这里从require的参数(...)获取模块名称
local modName = ...
-- 模块的内部名称M
local M = {}
-- lua的全局变量默认存储地方为_G, _G[modName] = M 等价于定义一个名字为modName的全局变量
_G[modName] = M
-- require函数当一个函数无返回值的时候,会返回package.loaded[模块名]的值
-- 于是这样写就可以省去最后的return语句了
package.loaded[modName] = M
-- setfenv是lua版本的using namespace M,这样写就可以避免每次都加M.前缀了
-- 为了能够访问其他全局变量,把M的元表的__index字段设为_G,这样不在M表的函数和变量就会到_G表查找
setmetatable(M, {__index = _G})
setfenv(1,M)
-- 定义模块函数,注意,模块名称被省略
function add(c1,c2) ... end
-- 调用模块内部的函数,需要complex.前缀
function callAdd(c1,c2)
add(c1,c2)
end
-- 不用返回这个表
-- return M
上述的代码好麻烦,lua5.1提供了一个函数,完成等价功能,只需要这样写:
-- complex.lua
-- module等价于上述一大段函数, package.seeall让这个模块可以访问_G中的变量
-- 如果只调用mudule(...)就不能访问
module(..., package.seeall)
-- 定义模块函数,注意,模块名称被省略
function add(c1,c2) ... end
-- 调用模块内部的函数,需要complex.前缀
function callAdd(c1,c2)
add(c1,c2)
end
-- 不用返回这个表
-- return M