Lua极简入门指南(六):模块
从用户的角度来看,一个模块能够通过require加载并返回一个table,模块导出的接口都被定义在此table中(此table被作为一个namespace)。所有的标准库都是模块。标准库被预先加载了,就像这样:
math=require'math' string=require'string'
require函数
使用require函数加载模块能够避免多次重复加载模块。加载一个模块:
require'modulename'
模块名(modulename)不那么准确的来说就是一个文件名(Lua文件或者是C库)。一个模块被加载后会被缓存到pacakge.loaded[modulename]中。看一个例子:
--test.lua print'HelloWorld'
在test.lua的相同目录下创建main.lua文件:
--main.lua require'test'
我们可以尝试多次requiretest.lua文件,但最终只会输出一次HelloWorld。如果我们希望require重新加载模块,那么可以清理package.loaded:
package.loaded[modulename]=nil
范例:
require'test' -->HelloWorld package.loaded.test=nil require'test' -->HelloWorld
编写模块
编写一个模块很简单,我们先创建一个table然后把需要导出的接口放入table中,最后返回此table:
--test.lua localexports={} functionexports.foo() print'HelloWorld' end returnexports
模块的返回值会被赋值给package.loaded[modulename]:
assert(require'test'==package.loaded.test)
如果模块不返回值,那么package.loaded[modulename]的值将为true:
--假定test.lua是一个空文件 localt=require'test' print(t) -->true print(package.loaded.test) -->true
更多的编写模块的方法见:http://lua-users.org/wiki/ModulesTutorial
查找模块
如果一个模块使用Lua编写,那么将在package.path中查找,如果一个模块使用C编写,那么将在package.cpath中查找。package.path和package.cpath是一个分号分隔的路径列表,例如:
C:\bin\lua\lua\?.lua;C:\bin\lua\lua\?\init.lua;C:\bin\lua\?.lua;C:\bin\lua\?\init.lua;.\?.lua
每一个路径都有一个?,真正的查找路径是将?替换为模块名之后的路径。
实际上,我们可以自定义查找模块的规则(通过向package.searchers中添加适当的searcher函数实现),例如我们可以把所有模块保存在一个加密并压缩的zip文件中。
一个模块命名为mod.sub,其是mod的子模块。在查找模块时,mod.sub中的.号会被转换为目录分隔符。假定路径列表如下:
C:\bin\lua\lua\?.lua;.\?.lua
那么require‘a.b'将尝试打开文件:
C:\bin\lua\lua\a\b.lua .\a\b.lua