hand
_1_34_39
4
返回栏目
1k
2k
1k
2k
1k
1k
2k
2k
2k
2k
2k
2k
3k
3k
2k
2k
2k
1k
2k
2k
2k
2k
2k
2k
2k
2k
1k
1k
1k
2k
1k
1k
2k
1k
2k
2k
2k
2k
2k
2k
2k
1k
2k
2k
2k
2k
2k
3k
2k
2k
6k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
2k
3k
2k
2k
2k
2k
2k
3k
3k
3k
1k
3k
3k
5k
2k
2k
2k
1k
1k
2k
2k
1k
1k
1k
2k
2k
2k
2k
2k
2k
2k
2k
3k
2k
2k
2k
2k
3k
3k
2k
2k
2k
2k
4k
2k
3k
2k
3k
2k
3k
2k
3k
2k
2k
2k
3k
返回Lua栏目
作者:
贺及楼
成为作者
更新日期:2025-02-27 21:50:32
在 Lua 编程中,模块是组织代码的重要方式,它允许我们将相关的函数、变量等封装在一起,提高代码的复用性和可维护性。而理解 Lua 的模块加载机制,尤其是加载顺序、搜索路径和加载过程,对于高效使用模块至关重要。本文将深入探讨这些内容,并通过示例代码进行演示。
在 Lua 中,我们通常使用 require
函数来加载模块。require
函数接受一个模块名作为参数,尝试找到并加载对应的模块。例如:
-- 加载名为 "mymodule" 的模块
local mymodule = require("mymodule")
当调用 require
函数时,Lua 会按照一定的规则去搜索并加载模块。
Lua 使用 package.path
(用于 Lua 文件)和 package.cpath
(用于 C 动态链接库)来确定搜索路径。这两个变量都是字符串,其中包含多个搜索路径,每个路径之间用分号分隔。
package.path
package.path
用于搜索 Lua 文件,其默认值通常是根据操作系统和 Lua 安装路径来确定的。我们可以通过以下代码查看当前的 package.path
:
print(package.path)
输出结果可能类似于:
./?.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua
这里的 ?
是一个占位符,表示模块名。例如,如果我们要加载 mymodule
模块,Lua 会依次尝试以下路径:
./mymodule.lua
/usr/local/share/lua/5.4/mymodule.lua
/usr/local/share/lua/5.4/mymodule/init.lua
/usr/local/lib/lua/5.4/mymodule.lua
/usr/local/lib/lua/5.4/mymodule/init.lua
package.cpath
package.cpath
用于搜索 C 动态链接库,同样可以通过以下代码查看:
print(package.cpath)
其默认值也会根据系统和安装路径有所不同,格式与 package.path
类似,同样使用 ?
作为占位符。
我们可以通过修改 package.path
和 package.cpath
来添加或修改搜索路径。例如,添加一个自定义的搜索路径:
-- 添加自定义 Lua 文件搜索路径
package.path = package.path.. ";./custom/?.lua"
-- 添加自定义 C 动态链接库搜索路径
package.cpath = package.cpath.. ";./custom/?.so"
当调用 require
函数时,Lua 的加载过程如下:
Lua 会首先检查 package.loaded
表,该表用于缓存已经加载的模块。如果模块名已经存在于 package.loaded
表中,require
函数会直接返回该表中对应的值,而不会再次加载模块。例如:
-- 第一次加载模块
local mymodule1 = require("mymodule")
-- 第二次加载模块,会直接从缓存中获取
local mymodule2 = require("mymodule")
print(mymodule1 == mymodule2) -- 输出 true
如果模块没有被缓存,Lua 会根据 package.path
中的搜索路径依次查找对应的 .lua
文件。如果找到文件,会将其内容作为 Lua 代码执行,并将执行结果存储在 package.loaded
表中,然后返回该结果。
如果没有找到对应的 .lua
文件,Lua 会根据 package.cpath
中的搜索路径依次查找对应的 C 动态链接库(如 .so
文件)。如果找到,会加载该动态链接库,并调用其中的初始化函数,将返回值存储在 package.loaded
表中,然后返回该结果。
如果在所有搜索路径中都没有找到对应的 Lua 文件或 C 动态链接库,require
函数会抛出一个错误。
下面是一个完整的示例,演示了模块加载的过程:
mymodule.lua
-- mymodule.lua
local M = {}
function M.hello()
print("Hello from mymodule!")
end
return M
main.lua
-- main.lua
-- 尝试加载模块
local mymodule = require("mymodule")
-- 调用模块中的函数
mymodule.hello()
-- 再次加载模块,验证缓存机制
local mymodule2 = require("mymodule")
print(mymodule == mymodule2) -- 输出 true
运行 main.lua
文件,输出结果如下:
Hello from mymodule!
true
步骤 | 描述 |
---|---|
检查缓存 | 查看 package.loaded 表,若模块已存在则直接返回对应值 |
搜索 Lua 文件 | 根据 package.path 中的搜索路径查找 .lua 文件,找到则执行并缓存结果 |
搜索 C 动态链接库 | 若未找到 .lua 文件,根据 package.cpath 中的搜索路径查找 C 动态链接库,找到则加载并缓存结果 |
抛出错误 | 若都未找到,抛出错误 |
通过理解 Lua 的模块加载机制、搜索路径和加载过程,我们可以更好地组织和管理代码,避免重复加载模块,提高程序的性能和可维护性。
Lua
整章节共127节
快分享给你的小伙伴吧 ~