> 技术文档 > Lua(模块与包)

Lua(模块与包)


Lua 模块的基本概念

Lua 中的模块是一个由函数、变量组成的代码库,通常保存在独立的 .lua 文件中。模块通过 return 语句导出其内容,供其他脚本调用。模块化设计可以提高代码复用性,便于管理。

创建模块

模块通常以 .lua 文件形式存在,文件内通过 return 返回一个表(table),表中包含模块的公开函数或变量。例如:

-- 文件名为 mymodule.lualocal M = {} -- 模块表function M.add(a, b) return a + bendfunction M.sub(a, b) return a - bendreturn M -- 导出模块

加载模块

Lua 5.1 及以上版本使用 require 函数加载模块。require 会搜索模块路径并执行文件,返回模块导出的内容:

local mymodule = require(\"mymodule\") -- 加载模块print(mymodule.add(1, 2)) -- 调用模块函数

模块搜索路径

require 通过 package.pathpackage.cpath 确定搜索路径。package.path 用于 .lua 文件,package.cpath 用于二进制模块(如 .dll.so)。默认路径包含当前目录和 Lua 安装路径。

print(package.path) -- 查看 Lua 模块搜索路径print(package.cpath) -- 查看二进制模块搜索路径

模块的局部变量

模块中未暴露的局部变量对外不可见,实现封装:

local M = {}local privateVar = 100 -- 局部变量,外部不可访问function M.getPrivate() return privateVarendreturn M

包管理工具

Lua 的包管理工具如 LuaRocks 可以安装和管理第三方模块。安装命令示例:

luarocks install luasocket

模块的缓存机制

require 会缓存已加载的模块,避免重复加载。可以通过 package.loaded 查看或清除缓存:

package.loaded[\"mymodule\"] = nil -- 清除模块缓存require(\"mymodule\") -- 重新加载

使用环境隔离

模块可以通过设置 _ENV 实现沙盒环境,避免污染全局命名空间:

local M = {}setmetatable(M, { __index = _G }) -- 继承全局环境_ENV = M -- 切换环境function add(a, b) return a + bendreturn M

模块的依赖管理

模块可以依赖其他模块,通过 require 引入:

local json = require(\"dkjson\") -- 引入第三方 JSON 模块local M = {}function M.toJson(t) return json.encode(t)endreturn M

动态加载模块

loadfiledofile 可以动态加载模块,但不推荐替代 require

local chunk = loadfile(\"mymodule.lua\") -- 加载但不执行local M = chunk() -- 执行并获取模块

模块的命名规范

Lua 模块通常使用小写字母和下划线命名,如 my_module.lua。避免与 Lua 关键字冲突。

模块的版本控制

在模块中定义版本号,便于管理:

local M = {}M._VERSION = \"1.0.0\"return M

模块的测试与调试

模块可以通过独立的测试脚本验证功能:

local mymodule = require(\"mymodule\")assert(mymodule.add(1, 2) == 3)

Lua 5.2 后的模块变化

Lua 5.2 移除了 module 函数,推荐直接使用 return table 的方式定义模块。

模块的打包与分发

将模块打包为 .rocks 文件或直接发布源码,便于其他开发者使用。LuaRocks 支持模块发布:

luarocks pack mymodule

模块的跨平台兼容性

确保模块代码兼容不同操作系统,避免路径硬编码:

local path_sep = package.config:sub(1,1) -- 获取系统路径分隔符local path = \"foo\" .. path_sep .. \"bar.lua\"

模块的元表应用

通过元表为模块添加默认方法或重载操作符:

local M = {}setmetatable(M, { __add = function(a, b) return a.value + b.value end})M.value = 10return M