require 使用 package.path(Lua 文件)和 package.cpath(C 庫)作為搜索路徑,路徑項以 ; 分隔,? 為模塊名佔位符。
-- package.path 示例
;.\?.lua;D:\Lua\5.1\lua\?.lua;D:\Lua\5.1\lua\?\init.lua;...
-- require "mod" 依次嘗試
mod
mod.lua
c:\windows\mod
/usr/local/lua/mod/mod.lua
package.loaded[modname],若存在直接返回loadfile 加載;C 庫 → loadlib 加載package.loaded[modname] 並返回require "jellythink"
-- 錯誤信息會列出所有嘗試過的路徑
C 庫模塊無法修改內部 luaopen_* 函數名,但 require 支援連字符重命名:
require "a-b" 會查找 luaopen_b 而非 luaopen_a-bmylib-v1, mylib-v2)local M = {} -- 內部實現表
function M.new(r, i) return {r = r, i = i} end
M.i = M.new(0, 1) -- 常量
function M.add(c1, c2)
return M.new(c1.r + c2.r, c1.i + c2.i)
end
function M.sub(c1, c2)
return M.new(c1.r - c2.r, c1.i - c2.i)
end
return M -- 導出
保存為 complex.lua,使用時:
local complex = require "complex"
local c1 = complex.new(1, 2)
local c2 = complex.new(3, 4)
print(complex.add(c1, c2).r) -- 4
local moduleName = ...
local M = {}
_G[moduleName] = M
package.loaded[moduleName] = M -- 省略 return
function M.new(r, i) return {r=r, i=i} end
-- ... 其他函數直接用 M.xxx
-- 無需 return M
優點:文件重命名即模塊重命名,內部無硬編碼模塊名。
為模塊設置專屬 _ENV,所有全局變量自動收集到模塊 table:
local _ENV = {}
function new(r, i) return {r=r, i=i} end
i = new(0, 1)
function add(c1, c2) return new(c1.r+c2.r, c1.i+c2.i) end
return _ENV
此模式下無需前綴 M.,代碼極度簡潔。
package.loaded[mod] = nil 後再 require現代 Lua 模塊開發核心原則:局部表實現、返回導出、利用 package.loaded 緩存、善用 _ENV 簡化代碼。摒棄舊版 module(),擁抱模塊化、可重命名、可熱更新的模塊設計。