package.path 和 package.cpath
配置 Lua 模块和 C 模块的搜索路径。
package.path 和 package.cpath 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
package.path 的内容
package.path 是一个由分号分隔的搜索模式字符串。每个模式都包含一个 ? 占位符,该占位符会被模块名称替换(其中的点会转换为目录分隔符)。Lua 会按顺序尝试每个模式,直到找到文件为止。
print(package.path)
-- ./?.lua;./?.luac;/usr/local/share/lua/5.4/?.lua;...
-- Dots in module names become directory separators
-- require("foo.bar") -> searches for foo/bar.lua
print(("foo.bar"):gsub("%.", "/")) -- foo/bar添加搜索路径
将路径添加到 package.path 的开头,可以增加搜索目录。追加路径则会添加优先级较低的位置。在任何需要使用新路径的 require 调用之前设置它。
-- Add multiple directories
package.path = table.concat({
"./?.lua",
"./lib/?.lua",
"./lib/?/init.lua",
package.path, -- keep existing paths
}, ";")
-- Now require("json") searches:
-- ./json.lua -> ./lib/json.lua -> ./lib/json/init.lua -> ...用于 C 扩展的 package.cpath
package.cpath 是 C 扩展模块的搜索路径(共享库:Linux 上为 .so,Windows 上为 .dll,macOS 上为 .dylib)。其命名约定与系统共享库的约定一致。
print(package.cpath)
-- ./?.so;/usr/local/lib/lua/5.4/?.so;...
-- Add a local C library directory
package.cpath = "./clib/?.so;" .. package.cpath
-- require("myextension") will now search:
-- ./clib/myextension.soLUA_PATH 环境变量
LUA_PATH 环境变量会设置 package.path 的初始值。LUA_PATH 中的 ;; 会被默认路径替换。您可以使用它配置搜索路径,而无需修改脚本——这对部署很有用。
-- Set before launching Lua:
-- export LUA_PATH="./?.lua;./lib/?.lua;;"
-- The ";;" expands to the built-in default path
-- In Lua, check what was set:
print(package.path)
-- You can also use LUA_CPATH for C paths:
-- export LUA_CPATH="./clib/?.so;;"package.searchpath
package.searchpath(name, path) 会在路径字符串中搜索与名称匹配的文件。它会返回找到的第一个匹配项;如果没有找到,则返回 nil 和一条列出所有尝试位置的错误消息。这适合在不实际加载文件的情况下查找文件。
local file, err = package.searchpath("json", package.path)
if file then
print("Found:", file)
else
print("Not found. Tried:\n" .. err)
end
-- Useful for checking if a module exists:
local function moduleExists(name)
return package.searchpath(name, package.path) ~= nil
end
print(moduleExists("json"))require 搜索算法
调用 require("mod") 时,Lua 会按以下顺序执行:(1) 检查 package.loaded;(2) 检查 package.preload;(3) 在 package.path 中搜索 .lua 文件;(4) 在 package.cpath 中搜索 C 库。第一个匹配项会被采用。
-- Simulate what require does:
local function myRequire(name)
-- 1. Check cache
if package.loaded[name] ~= nil then
return package.loaded[name]
end
-- 2. Check preload
if package.preload[name] then
return package.preload[name]()
end
-- 3. Search path
local file = package.searchpath(name, package.path)
if file then
return dofile(file) -- simplified
end
error("module not found: " .. name)
end加载器函数
package.searchers(以前称为 package.loaders)是一个函数数组,用于尝试查找并加载模块。您可以向此表中添加自定义搜索器。每个搜索器都会接收模块名称,并返回一个加载器函数或 nil。
-- Add a custom searcher that loads from a table
local builtins = {
myconfig = function()
return {host="localhost", port=8080}
end
}
table.insert(package.searchers, 1, function(name)
local loader = builtins[name]
if loader then return loader end
end)
local cfg = require("myconfig")
print(cfg.host, cfg.port) -- localhost 8080模块名称约定
模块名称使用点表示层级结构,例如 "mylib.utils"。按照惯例,顶层命名空间使用项目或组织名称,以避免冲突。通常使用小写字母。模块名称中应避免使用连字符(请改用下划线),因为连字符会与 Lua 语法冲突。
-- Good: hierarchical, lowercase
-- require("myapp.db.connection")
-- require("myapp.utils.string")
-- Bad: dashes cause syntax issues in dot notation
-- local my-module = require("my-module") -- SYNTAX ERROR
local mymodule = require("my_module") -- ok路径调试
当 require 找不到模块时,错误消息会列出所有尝试过的路径。打印 package.path 可以查看搜索顺序。使用 package.searchpath 可以交互式检查特定模块的路径。
-- Debug require failures:
local ok, err = pcall(require, "missing_module")
if not ok then
-- The error message shows all tried paths
print("require failed:")
print(err)
print("\nCurrent package.path:")
for path in package.path:gmatch("[^;]+") do
print(" " .. path)
end
end重置为默认路径
如果您希望获得不包含系统默认值的简洁、最小路径,可以完全重置 package.path。这对文件系统受限或处于沙箱环境中的嵌入式 Lua 环境很有用。
-- Minimal path for embedded environment
package.path = "./?.lua;./lib/?.lua"
package.cpath = "./?.so"
-- Or get just the current directory patterns:
local function justLocal()
return "./?.lua;./?/init.lua"
end
print("Minimal path:", justLocal())快速检查
package.path 模式中的 ? 表示什么?
回顾:package.path
总结:
package.path:Lua 文件搜索模式;?= 模块名称package.cpath:C 库搜索模式- 在开头添加路径,以增加目录的优先级
LUA_PATH/LUA_CPATH环境变量用于设置初始路径package.searchpath:检查是否能找到模块- 通过
package.searchers添加自定义搜索器
常见问题解答
「package.path 和 package.cpath」课时是免费的吗?
是的 — 「package.path 和 package.cpath」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「package.path 和 package.cpath」这节课中我会学到什么?
配置 Lua 模块和 C 模块的搜索路径。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「package.path 和 package.cpath」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- require 函数
- 编写模块文件
- package.path 和 package.cpath
- 模块模式和最佳实践