Appearance
模块与包
模块是 Lua 中用于组织代码的方式,它允许我们将相关的函数和变量封装在一起,以便于重用。本章节将介绍 Lua 中模块的定义、加载和使用方法。
模块的定义
在 Lua 中,模块通常是一个表,其中包含函数和变量:
lua
-- mymodule.lua
local M = {}
function M.add(a, b)
return a + b
end
function M.sub(a, b)
return a - b
end
M.pi = 3.1415926535898
return M模块的加载
使用 require 函数加载模块:
lua
local mymodule = require("mymodule")
print(mymodule.add(10, 5)) -- 输出 15
print(mymodule.sub(10, 5)) -- 输出 5
print(mymodule.pi) -- 输出 3.1415926535898模块的搜索路径
当使用 require 加载模块时,Lua 会在以下路径中搜索模块:
- 环境变量
LUA_PATH指定的路径 - Lua 安装目录中的
lua文件夹 - 当前工作目录
LUA_PATH 的默认值通常是:
./?.lua;./?/init.lua;/usr/local/share/lua/5.3/?.lua;/usr/local/share/lua/5.3/?/init.lua;/usr/local/lib/lua/5.3/?.lua;/usr/local/lib/lua/5.3/?/init.lua模块的组织
单文件模块
最简单的模块是一个单独的 .lua 文件,如前面的 mymodule.lua 示例。
目录模块
对于较大的模块,可以将其组织为一个目录,目录中包含一个 init.lua 文件:
mymodule/
init.lua
utils.lua
constants.luainit.lua 文件会被自动加载:
lua
-- mymodule/init.lua
local M = {}
M.utils = require("mymodule.utils")
M.constants = require("mymodule.constants")
function M.add(a, b)
return a + b
end
return M模块的访问控制
私有成员
在模块内部,可以使用局部变量和函数来创建私有成员:
lua
-- mymodule.lua
local M = {}
-- 私有函数
local function privateFunction()
print("This is a private function")
end
-- 公共函数
function M.publicFunction()
privateFunction()
print("This is a public function")
end
return M公共成员
模块返回的表中的成员都是公共的:
lua
local mymodule = require("mymodule")
mymodule.publicFunction() -- 输出 This is a private function
-- 输出 This is a public function
mymodule.privateFunction() -- 报错,因为 privateFunction 是私有的模块的重命名
使用 require 加载模块时,可以给模块起一个别名:
lua
local mm = require("mymodule")
print(mm.add(10, 5)) -- 输出 15模块的重载
默认情况下,require 会缓存已加载的模块,再次调用 require 时会返回缓存的模块:
lua
local m1 = require("mymodule")
local m2 = require("mymodule")
print(m1 == m2) -- 输出 true,因为它们是同一个模块如果需要重新加载模块,可以先从 package.loaded 中删除模块,然后再次调用 require:
lua
package.loaded["mymodule"] = nil
local m3 = require("mymodule")
print(m1 == m3) -- 输出 false,因为 m3 是重新加载的模块标准库模块
Lua 提供了多个标准库模块:
math:数学函数string:字符串操作table:表操作io:输入/输出操作os:操作系统接口debug:调试接口coroutine:协同程序
示例:使用 math 模块
lua
print(math.pi) -- 输出 3.1415926535898
print(math.sqrt(16)) -- 输出 4
print(math.sin(math.pi / 2)) -- 输出 1示例:使用 string 模块
lua
local str = "Hello World"
print(string.upper(str)) -- 输出 HELLO WORLD
print(string.sub(str, 1, 5)) -- 输出 Hello示例:使用 table 模块
lua
local t = {3, 1, 4, 1, 5}
table.sort(t)
for i, v in ipairs(t) do
print(v)
end第三方模块
Lua 有丰富的第三方模块,可以通过 LuaRocks 包管理器安装:
bash
luarocks install luasocket安装后,可以使用 require 加载第三方模块:
lua
local socket = require("socket")
print(socket._VERSION)模块的应用
示例 1:创建一个数学工具模块
lua
-- mathutils.lua
local M = {}
function M.add(a, b)
return a + b
end
function M.sub(a, b)
return a - b
end
function M.mul(a, b)
return a * b
end
function M.div(a, b)
if b == 0 then
error("Division by zero")
end
return a / b
end
function M.pow(a, b)
return a ^ b
end
function M.sqrt(a)
return math.sqrt(a)
end
return M示例 2:创建一个字符串工具模块
lua
-- stringutils.lua
local M = {}
function M.trim(str)
return str:gsub("^%s*", ""):gsub("%s*$", "")
end
function M.split(str, sep)
local t = {}
for word in str:gmatch("([^" .. sep .. "]+)") do
table.insert(t, word)
end
return t
end
function M.startsWith(str, prefix)
return str:sub(1, #prefix) == prefix
end
function M.endsWith(str, suffix)
return str:sub(-#suffix) == suffix
end
return M小结
本章节介绍了 Lua 中模块的定义、加载、搜索路径、组织、访问控制、重命名、重载,以及标准库模块和第三方模块的使用。掌握这些内容,对于编写 Lua 程序非常重要。