module函数

模块的基本编写方法

local M = {}
local modname = 'a'
_G[modname] = M
package.loaded[modname] = M

function M.play()
    print('play')
end

function M.say()
    print('say')
    M.play()
end

return M

这里的问题是模块内函数之间的调用仍然要保留模块名的限定符,好比say中调用play方法就须要M.play。函数

使用环境

解决上面那个问题能够用setfenv把当前模块的全局环境设置为M,因而,定义函数的时候就不用加上M,模块中函数间的调用也不须要加M限定。lua

local M = {}
local modname = 'a'
_G[modname] = M
package.loaded[modname] = M
setfenv(1, M)

function play()
    -- print('play')
end

function say()
    -- print('say')
    play()
end

return M

上面把print注释掉了,是由于这个时候调用play或者say方法会报错,大概是说没有print这个东西。由于当前的全局环境变了,不是_G而是M,M中固然没有print。那要如何使用到_G中的全局变量呢?元表。code

local M = {}
local modname = 'a'
_G[modname] = M
package.loaded[modname] = M

setmetatable(M, {__index = _G})
setfenv(1, M)

使用module

能够使用module函数来替换下面的代码io

local M = {}
local modname = 'a'
_G[modname] = M
package.loaded[modname] = M

setfenv(1, M)

上面的能够简化为table

module('a')

module默认是不提供外部访问的,也就是说这个时候print这些仍是不能用的。function

若是要加上setmetatable(M, {__index = _G})的效果,须要加上package.seeall参数,如class

module('a', package.seeall)

稍微一个总结:使用module来建立模块,定义函数以及模块内函数间的调用均可以不用加上限定附,好比上面的M。还有就是能够不用写return M,以及能够访问到_G中的全局变量。变量

附:module

setfenv(f, table):设置一个函数的环境meta

  (1)当第一个参数为一个函数时,表示设置该函数的环境

  (2)当第一个参数为一个数字时,为1表明当前函数,2表明调用本身的函数,3表明调用本身的函数的函数,以此类推

  所谓函数的环境,其实一个环境就是一个表,该函数被限定为只能访问该表中的域,或在函数体内本身定义的变量。

相关文章
相关标签/搜索