关于lua的require使用
来源:互联网 发布:北京单身公寓 知乎 编辑:程序博客网 时间:2024/05/16 12:48
为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来。现在看看lua的require的处理流程。
函数原型:require(modname) ---modname ---->加载的模块名称
首先Lua提供高级的require函数来加载运行库。粗略的说require和dofile完成同样的功能但有两点不同:
1、require会搜索目录加载文件
2、require会判断是否文件已经加载避免重复加载同一文件。
由于上述特征,require在Lua中是加载库的更好的函数。
require使用的路径和普通的路径还是有些区别,我们一般见到的路径都是一个目录列表。require的路径是一个模式列表,每一个模式指明一种由虚文件名(require的参数modname)转成实文件名的方法。更明确地说,每一个模式是一个包含可选的问号(?)的文件名。匹配的时候Lua会首先将问号用虚文件名替换,然后看是否有这样的文件存在。如果不存在继续用同样的方法用第二个模式匹配。例如,路径如下:
?; ?.lua; c:\windows\?; /usr/local/lua/?/?.lua调用require("add")时会试着打开以下这些文件:
addadd.luac:\windows\add/usr/local/lua/add/add.lua为了确定路径,Lua首先检查全局变量LUA_PATH是否为一个字符串,如果是则认为这个串就是路径;否则require检查环境变量LUA_PATH的值,如果两个都失败require使用固定的路径(典型的"?;?.lua").
require函数的实现原理如下:
--require 函数的实现 function require(name) if not package.loaded[name] then local loader = findloader(name) //这一步演示在代码中以抽象函数findloader来表示 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
require(在lua中它是ll_require函数)函数会在路径中搜索输入的文件路径,大致流程如下:
1、package.loaded
一个用于控制哪些模块已经加载的表,该表由require使用。当require一个模块名为modname的模块且package.loaded[modname]不为false时,require仅返回package.loaded[modname]存储的值.
2、 package.preload
为特定模块存储加载器的一个表。查找modname, 如果preload存在,那么就把它作为loader,调用loader(L)
3、package.path
查找lua库modname,这个库是通过module函数定义的,对于顶层的lua库,文件名和库名是一 样的而且不需要调用显式地在lua文件中调用module函数(在ll_require函数中可以看到处理方式),也就是说lua会根据lua文件直接完 成一个loader的初始化过程。
4、package.cpath(实现lua调用C函数)
查找c库,这个库是符合lua的一些规范的(export具有一定特征的函数接口),lua先已动态的方式加载该c库(.so),然后在库中查找并调用相应名字的接口,例如:luaopen_hello_world
5、已第一个"."为分割,将模块名划分为:(main, sub)的形式,根据package.cpath查找main,如果存在,就加载该库并查询相应的接口:luaopen_main_sub,例如:先查找 hello库,并查询luaopen_hello_world接口
6、得到loder后,用modname作为唯一的参数调用该loader函数。当然参数是通过lua的栈传递的,所以loader的原型必须符合lua的规范:int LUA_FUNC(lua_State *L)
ll_require会将这个loader的返回值符给package.loaded[modelname],如果loader不返回值同时 package.loaded[modelname]不存在时, ll_require就会把package.loaded[modelname]设为true。最后ll_reuqire把package.loaded [modelname]返回给调用者。
require的另一个功能是避免重复加载同一个文件两次。Lua保留一张所有已经加载的文件的列表(使用table保存)。如果一个加载的文件在表中存在require简单的返回;表中保留加载的文件的虚名,而不是实文件名。所以如果你使用不同的虚文件名require同一个文件两次,将会加载两次该文件。比如require "foo"和require "foo.lua",路径为"?;?.lua"将会加载foo.lua两次。我们也可以通过全局变量_LOADED访问文件名列表,这样我们就可以判断文件是否被加载过;同样我们也可以使用一点小技巧让require加载一个文件两次。比如,require "foo"之后_LOADED["foo"]将不为nil,我们可以将其赋值为nil,require "foo.lua"将会再次加载该文件。
- 关于lua的require使用
- Lua的require使用
- 【Lua】require 的使用
- Lua的require使用
- lua中require的使用
- lua的require
- Lua 的require
- Lua的require机制
- lua关于require和package.loaded 之间的关系
- lua进阶6--使用require 函数进行文件的调用
- Lua的require的特性
- lua的require和LuaLoadChunksFromZIP
- Lua require
- Lua require
- lua -require
- lua require
- lua require
- Lua-require
- jquery全选/jquery全不选/jquery反选
- boost.asio系列——io_service
- 第十四周上机项目二.1
- 第14周项目4-电子词典(二分法查找)
- 从B表里取字段,更新A表的值
- 关于lua的require使用
- Cannot open precompiled header file: 'Debug/*.pch': No such file or directory
- Flex系列:FLEX动画效果
- 第十四周项目1折腾二维数组
- Rails使用will_paginate插件进行分页
- Oracle常用命令笔记
- 学习C++/CLI
- 看<黄金时代>有感
- 微信通过某个事件推送消息