lua中require、dofile、loadfile对比

一、require

require(moduleName):用来加载模块;其参数只要是文件名即可;利用模式匹配搜索加载文件;require只会被调用执行一次,会判断文件是否被加载避免重复加载; 

(1)模式匹配

require的路径是一个模式列表,每一个模式指明一种由虚文件名(require的参数)转成实文件名的方法;每一个模式是一个包含可选的问号的文件名。匹配的时候Lua会首先将问号用虚文件名替换,然后看是否有这样的文件存在。如果不存在继续用同样的方法用第二个模式匹配;例如:

?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
require "test" --会试图打开以下文件进行匹配
test
test.lua
c:\windows\test
/usr/local/lua/test/test.lua

(2)lua中require的加载模块过程

a.首先在package.loaded查找modelname 如果该模块已经存在 则直接返回它的值
b.未找到 在package.perload查找modelname 如果找到一个函数与传入的modelname相同 则将其作为该模块的加载器
c.b步骤未找到 则根据package.path的模式查找lua库中的modelname 顶层lua库与文件名相同 
    可以直接通过lua文件直接完成loader的初始化过程
d.C步骤未找到 则根据package.cpath查找C库 lua先动态加载C库 之后在C库找并调用相应名字的借口
e.以第一个"."为分割 将模块划分成(main, sub)的形式 根据package.cpath查找main 
    如果存在  就加载该库并查询相应的接口:luaopen_main_sub 

f.得到loader后 用modelname作为唯一的参数调用该loader函数 
    参数通过lua的栈进行传递 loader原型必须符合lua的规范 int lua_func(lua_Statae *L)

ll_require将返回值存在package.loaded[modelname]中   
   如果loader不返回值同时package.loaded[modelname]不存在时, ll_require就会把package.loaded[modelname]设为true
   最后ll_reuqire把package.loaded[modelname]返回给调用者。 

二、dofile

dofile(modulename) 参数必须带上文件名后缀 而且需要文件所在的绝对路径

它得主要功能:读入加载的文件进行编译和执行 每调用一次dofile 文件都会被编译和执行一次

三、loadfile

loadfile(modulename) 只编译模块 但是不执行模块 loadfile将模块编译之后当作函数返回

hello.lua

function print_1()
    print("hello world")
end




test.lua

function main
 dofile("hello.lua")
 print("hello")
end


main()

如果dofile会执行文件里的函数 那么lua ./test.lua的结果为 hello world  但是结果为hello  并没有执行

猜你喜欢

转载自blog.csdn.net/weixin_41966991/article/details/88763096