模块基础 #
一、模块概述 #
1.1 什么是模块 #
模块是 Lua 组织代码的基本方式,一个模块就是一个返回表的 Lua 文件:
lua
-- mymodule.lua
local M = {}
M.version = "1.0"
function M.hello()
print("Hello from module!")
end
return M
1.2 模块的优势 #
- 代码组织:将相关功能组织在一起
- 命名空间:避免全局命名冲突
- 复用性:代码可以在多个项目中复用
- 封装性:隐藏实现细节
二、创建模块 #
2.1 基本模块 #
lua
-- math_utils.lua
local M = {}
M.PI = 3.14159
function M.square(x)
return x * x
end
function M.cube(x)
return x * x * x
end
function M.distance(x1, y1, x2, y2)
local dx = x2 - x1
local dy = y2 - y1
return math.sqrt(dx * dx + dy * dy)
end
return M
2.2 私有成员 #
lua
-- counter.lua
local M = {}
-- 私有变量
local count = 0
-- 私有函数
local function validate(n)
return type(n) == "number" and n >= 0
end
-- 公共接口
function M.increment(n)
n = n or 1
if validate(n) then
count = count + n
end
end
function M.get()
return count
end
function M.reset()
count = 0
end
return M
2.3 模块定义方式 #
lua
-- 方式1:返回表(推荐)
local M = {}
function M.func() end
return M
-- 方式2:直接返回
return {
func = function() end
}
-- 方式3:使用 module 函数(已弃用)
-- module("mymodule", package.seeall)
三、加载模块 #
3.1 require 函数 #
lua
-- 加载模块
local math_utils = require("math_utils")
-- 使用模块
print(math_utils.PI)
print(math_utils.square(5))
print(math_utils.distance(0, 0, 3, 4))
3.2 require 的工作原理 #
lua
-- require 的执行过程:
-- 1. 检查 package.loaded 表,如果已加载则返回缓存
-- 2. 搜索模块文件
-- 3. 编译并执行模块代码
-- 4. 将返回值存入 package.loaded
-- 5. 返回模块
-- 查看已加载的模块
for name, module in pairs(package.loaded) do
print(name, module)
end
3.3 模块搜索路径 #
lua
-- 查看搜索路径
print(package.path) -- Lua 模块路径
print(package.cpath) -- C 模块路径
-- 修改搜索路径
package.path = package.path .. ";./my_modules/?.lua"
3.4 模块搜索器 #
lua
-- 查看搜索器列表
for i, searcher in ipairs(package.searchers) do
print(i, searcher)
end
-- 搜索器执行顺序:
-- 1. package.preload 预加载表
-- 2. Lua 模块搜索器
-- 3. C 模块搜索器
-- 4. C 根模块搜索器
四、模块路径 #
4.1 路径格式 #
lua
-- package.path 中的占位符
-- ? 表示模块名
-- ; 分隔多个路径
-- 示例路径
-- ./?.lua
-- /usr/local/share/lua/5.4/?.lua
-- /usr/local/share/lua/5.4/?/init.lua
-- 加载 foo.bar 模块
-- 会搜索:./foo/bar.lua
local foo_bar = require("foo.bar")
4.2 设置路径 #
lua
-- 方法1:修改 package.path
package.path = "./lib/?.lua;./src/?.lua;" .. package.path
-- 方法2:设置环境变量
-- LUA_PATH="./lib/?.lua;;"
-- LUA_CPATH="./lib/?.so;;"
-- 方法3:在代码中设置
local function add_path(path)
package.path = path .. "/?.lua;" .. package.path
package.path = path .. "/?/init.lua;" .. package.path
end
五、模块模式 #
5.1 单例模式 #
lua
-- singleton.lua
local Singleton = {}
local instance = nil
function Singleton.get_instance()
if not instance then
instance = {
value = 0,
increment = function(self)
self.value = self.value + 1
end
}
end
return instance
end
return Singleton
5.2 类模式 #
lua
-- person.lua
local Person = {}
Person.__index = Person
function Person.new(name, age)
return setmetatable({
name = name,
age = age
}, self)
end
function Person:greet()
print("Hello, I'm " .. self.name)
end
function Person:get_age()
return self.age
end
return Person
5.3 命名空间模式 #
lua
-- myapp.lua
local MyApp = {}
MyApp.version = "1.0"
-- 子模块
MyApp.utils = require("myapp.utils")
MyApp.config = require("myapp.config")
MyApp.models = require("myapp.models")
return MyApp
六、模块重载 #
6.1 强制重载 #
lua
-- 清除模块缓存
package.loaded["mymodule"] = nil
-- 重新加载
local mymodule = require("mymodule")
6.2 热重载 #
lua
local function reload_module(name)
package.loaded[name] = nil
return require(name)
end
-- 开发时使用
local mymodule = reload_module("mymodule")
七、模块组织 #
7.1 目录结构 #
text
myproject/
├── main.lua
└── lib/
├── myapp/
│ ├── init.lua -- myapp 模块入口
│ ├── utils.lua -- myapp.utils
│ ├── config.lua -- myapp.config
│ └── models/
│ ├── init.lua -- myapp.models
│ └── user.lua -- myapp.models.user
└── thirdparty/
└── json.lua
7.2 init.lua 模式 #
lua
-- lib/myapp/init.lua
local M = {}
M.utils = require("myapp.utils")
M.config = require("myapp.config")
M.models = require("myapp.models")
M.version = "1.0"
return M
-- 使用
local myapp = require("myapp")
myapp.utils.helper()
八、最佳实践 #
8.1 模块命名 #
lua
-- 使用小写字母和点分隔
-- myapp.utils.string
-- myapp.models.user
-- 避免使用下划线
-- myapp_utils_string(不推荐)
8.2 模块文档 #
lua
--[[
模块名:math_utils
描述:数学工具函数
版本:1.0.0
作者:Your Name
用法:
local math_utils = require("math_utils")
print(math_utils.square(5))
]]
local M = {}
M.version = "1.0.0"
return M
8.3 错误处理 #
lua
local M = {}
function M.divide(a, b)
if b == 0 then
return nil, "除数不能为零"
end
return a / b
end
-- 使用
local result, err = M.divide(10, 0)
if not result then
print("错误:" .. err)
end
九、总结 #
本章介绍了 Lua 模块的基础知识:
- 模块概念:组织代码的基本方式
- 创建模块:返回表的 Lua 文件
- 加载模块:require 函数的使用
- 模块路径:搜索路径和设置
- 模块模式:单例、类、命名空间
- 模块组织:目录结构和最佳实践
下一章,我们将学习包管理。
最后更新:2026-03-27