Lua 初识之 require - 十五
模块类似于一个封装库,从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。
Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。以下为创建自定义模块 module.lua,文件代码格式如下
lua 工程下创建lua脚本,目录结构如下
TestB.lua
Module\TestA.lua
(1)部分
TestA.lua 代码如下
-- 定义一个全局的表 tableA
tableA = {}
-- 定义变量 a
tableA.a = 10
-- 定义函数 SSS
tableA.SSS = function()
print("tableA.SSS:"..tableA.a)
end
-- 定义全局函数 TestFunction
function TestFunction()
print("TestFunction:"..tableA.a)
end
-- 定义全局变量
abc = 100
-- 定义局部函数
local LocalFun = function()
print("LocalFun")
end
TestB.lua 脚本如下
-- 加载 Module\TestA.lua
require("/Module/TestA")
-- require "/Module/TestA"
-- require "/Module/TestA" 和 require("/Module/TestA") 写法不同而已,两种写法都可以
-- 此时可以调用 Module\TestA.lua 定义的所有全局 变量、函数了
print("tableA.a:"..tableA.a)
-- 调用 Module\TestA.lua 中表 tableA 的 SSS 函数
tableA.SSS()
--调用 Module\TestA.lua 中的全局函数 TestFunction
TestFunction()
--调用 Module\TestA.lua 中的全局变量 abc
print("abc:"..abc)
-- 调用 Module\TestA.lua 局部函数 LocalFun
LocalFun()
输出结果如下
tableA.a:10
tableA.SSS:10
This is TestFunction:
abc:100
lua: TestB.lua:30: attempt to call global 'LocalFun' (a nil value)
stack traceback:
TestB.lua:30: in main chunk
[C]: ?
因为 Module\TestA.lua 脚本中 表 tableA 是全局的
所以 TestB.lua 脚本执行 require(“/Module/TestA”) 后
可以在 TestB.lua 脚本中直接调用 表 tableA
因为 Module\TestA.lua 脚本中 变量 abc 是全局的
所以 TestB.lua 脚本执行 require(“/Module/TestA”) 后
可以在 TestB.lua 脚本中直接调用 变量 abc
因为 Module\TestA.lua 脚本中 函数 LocalFun 是局部函数
所以 TestB.lua 脚本执行 require(“/Module/TestA”) 后
在 TestB.lua 脚本中 调用 函数 LocalFun 是不可行的,因为访问不到
如果将 Module\TestA.lua 脚本中全局表 tableA = {}
改为 局部表 local tableA = {}
TestB.lua 脚本执行 require(“/Module/TestA”) 后,将无法访问到 Module\TestA.lua 脚本中的表 tableA
(2)部分
修改 Module\TestA.lua
-- 定义一个局部的表 tableA
local tableA = {}
-- 定义变量 a
tableA.a = 10
-- 定义函数 SSS
tableA.SSS = function()
print("tableA.SSS:"..tableA.a)
end
-- 定义全局函数 TestFunction
function TestFunction()
print("This is TestFunction:")
end-- 定义一个全局的表 tableA
tableA = {}
-- 定义变量 a
tableA.a = 10
-- 定义函数 SSS
tableA.SSS = function()
print("tableA.SSS:"..tableA.a)
end
-- 定义全局函数 TestFunction
function TestFunction()
print("TestFunction:"..tableA.a)
end
-- 定义全局变量
abc = 100
-- 定义局部函数
local LocalFun = function()
print("LocalFun")
end
-- 脚本最后返回 表 tableA
return tableA
两处修改,分别是
1.将 全局 tableA = {} 改为 内部/局部 local tableA = {}
2.最后一行添加 return tableA
修改 TestB.lua
-- 令 tableA_Alias = require "/Module/TestA",相当于其了一个别名
local tableA_Alias = require "/Module/TestA"
print("tableA_Alias.a:"..tableA_Alias.a)
-- 调用函数
tableA_Alias.SSS()
-- 调用函数
TestFunction()
-- 调用全局变量 aaa
print("abc:"..abc)
LocalFun()
输出结果
tableA_Alias.a:10
tableA.SSS:10
This is TestFunction:
abc:100
lua: TestB.lua:20: attempt to call global 'LocalFun' (a nil value)
stack traceback:
TestB.lua:20: in main chunk
[C]: ?
因为 Module\TestA.lua 最后一行 return tableA
所以 执行 local tableA_Alias = require “/Module/TestA” 后
tableA_Alias 其实上是等于 tableA,相当于 tableA 的一个引用或者别名
关于 require 的路径,当 执行 require 时,会从 package.path 路径中查找,package.path 包含了一系列路径,如果最终能找到 require* 的路径下的文件,则加载,如果找不到则加载失败
可以通过print 函数打印 package.path 包含的路径
print(package.path)
也可以自己设置 require 的访问路径
package.path = package.path …‘;…\?.lua’;
require 加载的脚本放在 package.loaded,当下次 require 时,会先从 package.loaded 中查找,如果已经存在,则不再重新加载