lua加载函数require和dofile

http://www.tuicool.com/articles/uyMRV3N

Lua提供高级的 require函数 来加载运行库。粗略的说require和 dofile 完成同样的功能但有两点不同:

1.  require会搜索目录加载文件

2. require会判断是否文件已经加载避免重复加载同一文件 。

由于上述特征,require在Lua中是加载库的更好的函数。

require使用的路径和普通我们看到的路径还有些区别,我们一般见到的路径都是一个目录列表。require的路径是一个模式列表,每一个模式指明一种由 虚文件名 (require的参数)转成实文件名的方法。更明确地说,每一个模式是一个包含可选的问号的文件名。匹配的时候Lua会首先将问号用虚文件名替换,然后看是否有这样的文件存在。如果不存在继续用同样的方法用第二个模式匹配。例如,路径如下:

?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua

调用require "lili"时会试着打开这些文件:

lili

lili.lua

c:\windows\lili

/usr/local/lua/lili/lili.lua

require关注的问题只有分号(模式之间的分隔符)和问号,其他的信息(目录分隔符,文件扩展名)在路径中定义。

为了确定路径,Lua首先检查 全局变量LUA_PATH 是否为一个字符串,如果是则认为这个串就是路径;否则require检查 环境变量LUA_PATH 的值,如果两个都失败;require使用 固定的路径 (典型的"?;?.lua")

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;/usr/local/default.lua

这种情况下,require没有匹配的时候就会使用这个固定的文件(当然这个固定的路径必须放在模式列表的最后才有意义)。在require运行一个chunk以前,它定义了一个全局变量_REQUIREDNAME 用来保存被required的虚文件的文件名。我们可以通过使用这个技巧扩展require的功能。举个极端的例子,我们可以 把路径设为"/usr/local/lua/newrequire.lua",这样以后每次调用require都会运行newrequire.lua,这种情况下可以通过使用_REQUIREDNAME的值去实际加载required的文件。

dofile:

我们知道一个lua文件是作为一个代码块(chunk)存在的,其实质就是一个函数,那么最简单的,我在一个外部lua文件中写一段代码,然后在主lua文件中用dofile调用,外部文件的代码块就会执行了。

外部lua文件在编译时并没有涉及词法域:

--outer.lua:  
         function sayHello()  
         print(name .. ",你好!")  
end  
--mian.lua:  
 require("outer")  
 name = "雷叔"  
 local name = "牛叔"  
 sayHello() 

运行结果是“雷叔,你好!”

形式上很类似C语言的#include<...>,在其他地方定义的函数,经这么引入文件之后就可以调用了。不过

lua并不是定义和实现分离 的语言

,这样是把整个定义部分都加载进来了哦。加载过程大致上是lua先加载这个外部文件,然后运行它。实际上这段外部代码是可以有返回值的,它的返回值 就是require的返回值。这里我们什么返回值都没有,执行这个外部代码的结果就是定义了这么个全局函数。注意是全局函数,虽然通常我们直接定义的函数 都是全局函数所以都没怎么注意过,要是非要定义个局部函数在主程序块里可就看不到了。另外和前面的情形一样,外部代码块只认识“雷叔”,“牛叔”是谁它根 本不知道。         可以在外部文件里定义一堆函数,然后全都加到全局环境下。不过全局的东西用起来要小心, 有一个原则是对全局的“污染”越小越好

。那么自然就引入了“模块” 的概念。

在lua中,模块由万能的table来充当

。最自然的想法就是定义一个table,然后把要定义的函数放在这个table里,最后返回这个 table就行了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值