更新时间:2023-11-24 12:34:16
require
函数在一系列查找模块的地方.可以通过调整全局表package
中的字段来广泛地定制位置的确切列表.
The require
function looks in a series of places to find a module. The exact list of places can be extensively customized by adjusting fields in the global table package
.
了解查找模块时使用的位置和名称的最简单方法是查看require
失败时产生的错误消息.例如,在我的PC上,Lua 5.1会这样说:
The easiest way to get a sense of how many places and names it uses when looking for a module is to look at the error message produced when require
fails. For example, on my PC, Lua 5.1 says this:
C:\Users\Ross>lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "xyzzy"
stdin:1: module 'xyzzy' not found:
no field package.preload['xyzzy']
no file '.\xyzzy.lua'
no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.lua'
no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy\init.lua'
no file 'C:\Program Files (x86)\Lua\5.1\xyzzy.lua'
no file 'C:\Program Files (x86)\Lua\5.1\xyzzy\init.lua'
no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.luac'
no file '.\xyzzy.dll'
no file '.\xyzzy51.dll'
no file 'C:\Program Files (x86)\Lua\5.1\xyzzy.dll'
no file 'C:\Program Files (x86)\Lua\5.1\xyzzy51.dll'
no file 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy.dll'
no file 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy51.dll'
no file 'C:\Program Files (x86)\Lua\5.1\loadall.dll'
no file 'C:\Program Files (x86)\Lua\5.1\clibs\loadall.dll'
stack traceback:
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?
>
内部查看后,它寻找xyzzy
的第一个真实"位置是在名为.\xyzzy.lua
的文件中.然后,它在找到lua.exe
的文件夹中尝试许多文件夹和名称.最后,它会寻找可能提供它的DLL.它搜索.lua
文件的文件夹列表由package.path
中的字符串值控制. (其中DLL的类似列表为package.cpath
.)在该值中,require
将用模块名称替换每个?
,然后尝试读取文件.使用第一个成功的方法.
After looking internally, the first "real" place it looks for xyzzy
is in the file named .\xyzzy.lua
. Then it tries a number of folders and names in the folder where lua.exe
was found. Finally, it looks for a DLL that might offer it. The list of folders it searches for a .lua
file is controlled by the string value in package.path
. (The comparable list for DLLs in is package.cpath
.) In that value, require
will replace each ?
with the module name, and then attempt to read the file. The first one to succeed is used.
(这里的故事稍微复杂一些;您可以创建搜索器",require
将使用它们来查找不同的位置,甚至更改内置搜索器的顺序,但这是一个高级主题.)
(The story here is slightly more complicated; you can create "searchers" that require
will use to look in different places, and even change the order of the built-in searchers, but that is an advanced topic.)
因此,只需将模块放在当前目录的Lua文件中就可以了,在为自己的模块调用require
之前调整package.path
可以解决您将遇到的大多数怪癖.
So just putting modules in Lua files in the current directory should work just fine, and adjusting package.path
before calling require
for your own modules can cover most quirks you will encounter.
最简单的说,模块就是可以存储在package.loaded
中的东西.一旦找到require
,它将使用该方法,因此对require
的多次调用将仅搜索一次,并且始终返回相同的值.
At its simplest, a module is just something that can be stored in package.loaded
. Which is what require
will do with it once it has been found, so that multiple calls to require
will only search once and always return the same value.
传统的答案是将某物"作为一个表,通常通常由可以被调用的函数填充,并偶尔具有值. math
模块是一个很好的例子:它提供了许多功能,例如sin
和cos
,以及有用的值math.pi
和math.huge
.
The traditional answer is for that "something" to be a table, usually mostly populated by functions that can be called, and occasionally having values. The math
module is a good example: it provides lots of functions like sin
and cos
, along with the useful value math.pi
and math.huge
.
除了存储在表中之外,模块中的功能没有什么特别的.像任何其他函数一样,它接受参数并返回零个或多个值.唯一真实的规则是模块不应更改或添加全局变量.
Aside from being stored in a table, there is nothing special about a function in a module. Like any other function, it takes parameters and return zero or more values. The only real rule is that a module should not change or add global variables.
因此,非常小的模块文件可以很简单:
So a very minimal module file can be as simple as:
return {
addtwo = function(a, b) return a+b end,
subtwo = function(x) return x-2 end,
}
如果存储为example.lua
,则可以这样使用:
which if stored as example.lua
could be used like this:
local example = require "example"
print(example.addtwo(2,2)) -- 4
print(example.subtwo(42)) -- 40
在大多数实际情况下,将所有代码都放在单个表声明中是不可行的.它不能很好地扩展,并且很难清楚地表达共享状态的功能之间的关系.
Sticking all your code in a single table declaration will not fly for most real cases. It does not scale well, and it makes it difficult to clearly express the relationship among functions that share state.
-- simple modules
-- capture the name searched for by require
local NAME=...
-- table for our functions
local M = { }
-- A typical local function that is also published in the
-- module table.
local function addtwo(a,b) return a+b end
M.addtwo = addtwo
-- Shorthand form is less typing and doesn't use a local variable
function M.subtwo(x) return x-2 end
return M
Lua 5.1包含一个名为module()
的标准函数,旨在在模块实现的顶部使用.从来不需要使用它,并且很快就形成了共识,即它没有像希望的那样有用.此后已弃用.
Lua 5.1 included a standard function named module()
intended to be used at the top of module implementations. Its use was never required, and a consensus formed fairly quickly that it was not as helpful an idea as hoped. It has since been deprecated.
结果,我上面显示的简单骨架没有使用它,并且可以移植到5.1版以后的所有Lua版本中.
As a result, the simple skeleton I show above does not use it, and is portable to all versions of Lua since 5.1.