前言:
- require加载时都要寻找哪些路径以及是如何在文件夹中寻找的这里不做讨论,因为我也不是很懂,想了解底层如何加载可以去看看其他博客,很多。
- 本文的目的是让你尽可能的理解require在Lua中的使用,以及一些应该注意的点。
理解:
- 可以把require当成C#中的using来看待,只不过Lua中的require是全局的,在一个脚本中引用之后在其他脚本也可以使用。
- 一个被require的脚本,本质上是被“执行”了一遍,将该脚本中的所有全局成员加载到了 _G 中,包括表、变量、方法,在方法外的执行语句也都会被执行,而方法被调用才会被执行。(不懂_G的同学可以看一下讲这个东西的博客)
- 为了避免重复加载,所有被require的脚本都会在package.loaded中进行“标记”,在加载时,会先去package.loaded中查找是否被引用过,如果有的话就不会再被加载一遍。(这一段话我写的是进行标记,因为我不确定在package.loaded中存储的到底是不是这个脚本的值,虽然其他博客说是在这个里面保存的值,但是我输出的是一个布尔类型的值。各位理解这句话的意思就行,就是被加载过就不会再被重复记载了;我的理解:所有被require的脚本都会在package.loaded中进行标记是否被加载过,如果存在,则不会被加载,使用时直接调用就能使用,因为他们全部在_G中存储;不知道我的理解对不对,各位有不同的意见或者好的想法欢迎讨论。)
(题外话:一些公司的Lua脚本会将基础的require放在一个脚本中统一调用。)
我创建了两个脚本,一个执行require,一个被require
--脚本名module.lua 这个是被require的脚本
module = {};
module.testFunc=function()
print("我是module表中的testFunc方法,我执行了");
end
--上面的module表是为了模拟类,所以和文件名保持一致,下面声明的a表和变量b都是可以用的
--但是在实际开发中,通常使用上面module表的规范,模拟类的引用。
print("单独的语句在被require时就会被执行");
function aloneTestFunc()
print("方法被调用时才会执行");
end
a={};
a.name="asd";
b="a";
local c="123";
试验一:
- 目的:提供require的使用方法,测试变量的输出以及方法的调用,以及单独语句是否会被执行。
- 方式:在脚本中require上面的module脚本,然后调用其中module表的方法,输出a表的变量、单独变量b、输出局部变量c。
require "module"; --require的格式(可能还有其他格式),后面跟脚本的名称。
module.testFunc(); --调用module表的这个方法
print(a.name); --输出a表的变量
print(b); --输出变量b
print(c); --输出局部变量c
运行结果:
>lua -e "io.stdout:setvbuf 'no'" "TestRequireChange.lua"
单独的语句在被require时就会被执行
我是module表中的testFunc方法,我执行了
asd
a
nil
>Exit code: 0
结论:
- 在脚本被require的时候会将脚本中的成员全部遍历,方法外的可执行语句直接执行。
- 可以调用被require脚本中的全局变量以及表中的成员,不能访问到被require脚本中的局部变量。
试验二:
- 目的:测试module模块,在其他脚本中不重新require,是否可以直接使用。
- 方式:先新建一个脚本,在其中写一个调用module模块中变量的方法,然后在另一个脚本中调用这个方法,测试是否可以直接使用。
这是新建的脚本
--脚本名requireTest.lua
function change()
print(a.name); --直接使用module脚本中的变量a 测试是否可以直接使用
end
在该脚本中引用module脚本和requireTest脚本,并调用requireTest脚本中的change方法。
require "module";
require "requireTest"
change();
运行结果:
>lua -e "io.stdout:setvbuf 'no'" "TestRequireChange.lua"
单独的语句在被require时就会被执行
asd
>Exit code: 0
总结:
- 只要是被require的脚本,在该项目中可以在其他脚本中进行调用。
- 提示:输出字符串“asd”的上面那个字符串,是require “module”时执行的,忘了的可以向上翻一下module脚本中的代码。
看到这里对require的使用就差不多了,更深一点和更复杂的使用会再其他文章里更新,这一篇文章先对require有一个初步的认识和知道使用它的方法。