Lua的require使用

本文介绍了Lua语言中require函数的基本用途及其实现原理,包括如何加载Lua模块、搜索路径配置、返回值特性及其内部实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Lua的require使用

  2151人阅读  评论(0)  收藏  举报
  分类:

目录(?)[+]

一.require的作用

  1. 加载指定的模块,相当与#include作用类似,加载了该模块,那么就可已使用模块中的全局函数和全局数据(如表等等) 
    注:实际上require “xxx”后,会将xxx中的全局函数和数据放到表_G中,所以也就能访问了。

2.例子

(1)main.lua

  require "test"
  require "showSome"

(2)test.lua

  function CallFunc()
  //这里能调用show(),证明了_G中有show这个元素
    show()
  end

(3)showSome.lua

  function show()
    print("it is showsome")
  end

(4)testLua.cpp

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    luaL_dofile(L,"Lua//main.lua");

    lua_getglobal(L,"CallFunc");
    lua_pcall(L,0,0,0);
    return 0;
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

二.require的搜索模块的路径

1.搜索lua文件的路径存放在变量package.path中,当lua启动后便以环境变量LUA_PATH的值来初始化这个变量,如果没有找到,则使用2中的的默认路径。如果lua还是无法找到与模块命符合的lua文件,那么它会开始找c程序库,路径储存在package.cpath中,这个变量通过环境变量LUA_CPATH来初始化。 
2.require的默认路径在:luaconf.h中,我们打开该文件搜索:LUA_PATH_DEFAULT ,便可以看到 
#deine LUA_PATH_DEFAULT \ 
LUA_LDIR”?.lua;” LUA_LDIR”?\init.lua;” \ 
LUA_CDIR”?.lua;” LUA_CDIR”?\init.lua;” \ 
LUA_SHRDIR”?.lua;” LUA_SHRDIR”?\init.lua;” \ 
“.\?.lua;” “.\?\init.lua;” \ 
LUA_CDIR”..\testLua\Lua\?.lua;” –这句是我自己加的

#deine LUA_CPATH_DEFAULT\ 
LUA_CDIR”?.dll;” \ 
LUA_CDIR”..\lib\lua\” LUA_VDIR “\?.dll;” \ 
LUA_CDIR”loadall.dll;” “.\?.dll”

注: 
1.修改了luaconf.h中的路径后,我们需要重新生成新的lua静态lib库,然后我们的程序使用新的静态lib,这样才能起效 
2.可以看到默认的路径的格式为: ?.lua , 所以我们require “xxx”,而不是require “xxx.lua”

三.require的返回值

require “xxx” 某个模块后

1.如果该模块自身有返回值,且模块加载成功,那么require 的返回值就是该模块的返回值 
2.如果模块没有返回值,如果require加载模块成功,就返回ture 
3.require 内部将返回值储存在:package.loaded表中。 
(即:package.loaded[xxx]中)

4.例子

(1)main.lua

x = require "test"

function Call()
    x.show()
end

(2)test.lua

local tb = {}
function tb.show()
    print("it is ok")
end

return tb

(3)testLua.cpp

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    luaL_dofile(L,"Lua//main.lua");

    lua_getglobal(L,"Call");
    lua_pcall(L,0,0,0);

    return 0;
}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

四. require的实现代码

function require(name)
    if not package.loaded[name] then
        local loader = findloader(name)
        if loader == nil then
            error("unable to load module" .. name)
        end

        package.loaded[name] = true
        local res = loader(name)
        if res ~= nil then
            package.loaded[name] = res
        end
    end
    return package.loaded[name]
end
<think>我们正在讨论Lua中的require函数。根据引用[3],require函数用于执行指定文件中的Lua代码,并且会检查模块是否已加载,如果已加载则直接返回缓存,否则加载并执行文件代码,并缓存结果。引用[4]也提到了require(modname)是基础函数之一。用户要求提供require函数的使用说明和示例。步骤:1.解释require函数的作用:加载模块,避免重复加载,返回模块的返回值。2.说明require的搜索路径:它会根据package.path和package.cpath来查找Lua文件和C模块。3.给出使用示例:包括如何编写一个模块(返回一个表)以及如何require这个模块。4.注意:require的参数是模块名,不需要带扩展名,并且模块名中的点会被转换为路径分隔符(例如,a.b会查找a/b.lua)。示例模块:假设我们有一个模块文件名为"mymodule.lua",其内容如下:```lualocalmymodule={}functionmymodule.add(a,b)returna+bendreturnmymodule```然后在另一个Lua文件中,我们可以这样使用:```lualocalmm=require("mymodule")print(mm.add(1,2))--输出3```另外,require还可以加载C模块(动态库),但这主要展示Lua模块。注意事项:-如果模块已经加载,require不会重新加载,而是返回之前缓存的模块。-如果找不到模块,require会抛出错误。可以使用pcall来捕获错误。示例:安全地require```lualocalok,mm=pcall(require,"mymodule")ifnotokthenprint("加载模块失败:",mm)elseprint(mm.add(1,2))end```根据引用[2],在C++中嵌入Lua时,可以通过luaL_requiref等函数来注册C模块,但用户当前问题集中在Lua中的使用,因此我们主要展示Lua中的用法。最后,生成相关问题。</think>### Lua `require` 函数使用详解 `require` 是 Lua 中用于加载模块的核心函数,其主要功能是**按需加载并缓存模块**,避免重复加载导致的资源浪费。以下是详细说明: #### 核心特性 1. **模块缓存机制** 首次加载模块时,`require` 会执行模块文件并缓存返回值;后续调用直接返回缓存值[^3]。 ```lua local mod1 = require("mymod") -- 首次加载,执行文件 local mod2 = require("mymod") -- 直接返回缓存值 print(mod1 == mod2) -- 输出 true ``` 2. **路径搜索规则** 按 `package.path` (Lua文件) 和 `package.cpath` (C模块) 路径查找文件[^4]。 ```lua print(package.path) -- 显示Lua模块搜索路径 ``` 3. **模块名转换** 将点号转换为路径分隔符(如 `a.b` → `a/b.lua`)。 --- #### 使用示例 ##### 1. 加载标准库模块 ```lua local math = require("math") print(math.sqrt(9)) -- 输出 3.0 ``` ##### 2. 加载自定义模块 **模块文件 `mymod.lua`:** ```lua local M = {} -- 创建模块表 function M.add(a, b) return a + b end return M -- 必须返回模块值 ``` **主程序:** ```lua local mymod = require("mymod") -- 加载模块(无.lua后缀) print(mymod.add(2, 3)) -- 输出 5 ``` ##### 3. 错误处理 ```lua local ok, mod = pcall(require, "non_existent") if not ok then print("加载失败:", mod) -- 输出错误信息 end ``` --- #### 注意事项 1. **模块必须返回值** 被加载文件需通过 `return` 返回模块对象(通常是表)[^4]。 2. **避免循环依赖** 模块A依赖B,B又依赖A会导致加载失败。 3. **与 `dofile` 的区别** | 特性 | `require` | `dofile` | |--------------|-------------------------|------------------------| | 缓存 | ✅ 避免重复加载 | ❌ 每次重新执行 | | 路径搜索 | ✅ 按 package.path 查找 | ❌ 需完整路径 | | 错误处理 | ❌ 直接抛出错误 | ✅ 可返回错误代码 | 4. **C模块加载** 支持加载C编写的动态库(通过 `package.cpath` 路径)[^2]。 --- #### 典型应用场景 - 代码模块化组织 - 插件系统动态加载 - 避免全局命名空间污染 - 资源延迟加载优化性能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值