第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但有一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目。
用 Lua 编程 | ||
第一部分。语言 第 8 章。编译、执行和错误 |
require
函数Lua 提供了一个更高级别的函数来加载和运行库,称为 require
。粗略地说,require
与 dofile
执行相同的工作,但有两个重要的区别。首先,require
在路径中搜索文件;其次,require
控制是否已经运行过某个文件,以避免重复工作。由于这些特性,require
是 Lua 中加载库的首选函数。
require
使用的路径与典型路径略有不同。大多数程序使用路径作为目录列表,在其中搜索给定文件。然而,ANSI C(Lua 运行的抽象平台)没有目录的概念。因此,require
使用的路径是一个模式列表,每个模式都指定将虚拟文件名(require
的参数)转换为真实文件名的备选方式。更具体地说,路径中的每个组件都是一个包含可选问号的文件名。对于每个组件,require
用虚拟文件名替换每个 `?
´,并检查是否存在具有该名称的文件;如果没有,则转到下一个组件。路径中的组件用分号分隔(在大多数操作系统中,分号很少用于文件名)。例如,如果路径是
?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua那么调用
require"lili"
将尝试打开以下文件
lili lili.lua c:\windows\lili /usr/local/lua/lili/lili.lua
require
修复的唯一内容是分号(作为组件分隔符)和问号;其他所有内容(例如目录分隔符或文件扩展名)都在路径中定义。
为了确定其路径,require
首先检查全局变量 LUA_PATH
。如果 LUA_PATH
的值为字符串,则该字符串为路径。否则,require
检查环境变量 LUA_PATH
。最后,如果两个检查都失败,require
使用固定路径(通常为 "?;?.lua"
,尽管在编译 Lua 时很容易更改该路径)。
require
的另一个主要工作是避免加载相同的文件两次。为此,它保留一个包含所有已加载文件名称的表。如果所需文件已在表中,则 require
只需返回。该表保留已加载文件的虚拟名称,而不是它们的真实名称。因此,如果您使用两个不同的虚拟名称加载相同的文件,它将被加载两次。例如,命令 require"foo"
后跟 require"foo.lua"
,路径为 "?;?.lua"
,将加载文件 foo.lua
两次。您可以通过全局变量 _LOADED
访问此控制表。使用此表,您可以检查已加载哪些文件;您还可以欺骗 require
再次运行文件。例如,在成功 require"foo"
之后,_LOADED["foo"]
将不会是 nil。如果您随后将 nil 分配给 _LOADED["foo"]
,则后续 require"foo"
将再次运行该文件。
组件不需要有问号;它可以是固定文件名,例如以下路径中的最后一个组件
?;?.lua;/usr/local/default.lua在这种情况下,每当
require
找不到其他选项时,它将运行此固定文件。(当然,只有将固定组件作为路径中的最后一个组件才有意义。)在 require
运行块之前,它定义一个全局变量 _REQUIREDNAME
,其中包含所需文件的虚拟名称。我们可以使用这些功能来扩展 require
的功能。在一个极端的例子中,我们可以将路径设置为类似于 "/usr/local/lua/newrequire.lua"
的内容,以便每次调用 require
都运行 newrequire.lua
,然后它可以使用 _REQUIREDNAME
的值来实际加载所需的文件。
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |