访问其他文件上的 Lua 函数

OT2*_*T2O 2 lua

嗨,我想将我的 Lua 文件分成两个文件。一个保存我的函数,一个可以调用它们。我对此进行了大量研究,我发现的所有资源都没有非常深入地解释这个过程。他们通常说使用:

require "subsystem.lua"
Run Code Online (Sandbox Code Playgroud)

我把它放在一个新的 Lua 文件的顶部,该文件保存在同一目录中,并且无法访问任何内容。

是否有我需要修改的配置文件?它在哪里?

Pau*_*nko 5

您需要做的是返回一个包含您要访问的字段的表,subsystem.lua然后在主文件中分配和使用该表中的字段。沿着这些路线的东西:

-- subsystem.lua

local function doSomething()
  -- do something useful here
end

local function doMore()
  -- do something else useful
end

return { doSomething = doSomething, doMore = doMore }

-- main.lua

local subsystem = require "subsystem" -- don't add `.lua` to your `require` call
subsystem.doSomething()
subsystem.doMore()
Run Code Online (Sandbox Code Playgroud)

您可能需要查看模块教程以获取详细信息。


RBe*_*eig 5

需要模块

require函数在一系列位置查找模块。可以通过调整全局表中的字段来广泛定制确切的地点列表package

了解在查找模块时使用了多少位置和名称的最简单方法是查看require失败时产生的错误消息。例如,在我的 PC 上,Lua 5.1 是这样说的:

C:\用户\罗斯> lua
Lua 5.1.4 版权所有 (C) 1994-2008 Lua.org, PUC-Rio
> 需要“xyzzy”
标准输入:1:找不到模块“xyzzy”:
        没有字段 package.preload['xyzzy']
        没有文件 '.\xyzzy.lua'
        没有文件 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.lua'
        没有文件 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy\init.lua'
        没有文件 'C:\Program Files (x86)\Lua\5.1\xyzzy.lua'
        没有文件 'C:\Program Files (x86)\Lua\5.1\xyzzy\init.lua'
        没有文件 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.luac'
        没有文件 '.\xyzzy.dll'
        没有文件 '.\xyzzy51.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\xyzzy.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\xyzzy51.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy51.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\loadall.dll'
        没有文件 'C:\Program Files (x86)\Lua\5.1\clibs\loadall.dll'
堆栈回溯:
        [C]:在函数“要求”中
        标准输入:1:在主块中
        [C]: ?
> 

在内部查看后,它寻找的第一个“真实”位置xyzzy在名为.\xyzzy.lua. 然后它会在lua.exe找到的文件夹中尝试多个文件夹和名称。最后,它寻找可能提供它的 DLL。它搜索.lua文件的文件夹列表由 中的字符串值控制package.path。(DLL 中的可比较列表是package.cpath。)在该值中,require将用?模块名称替换每个,然后尝试读取文件。使用第一个成功的。

(这里的故事稍微复杂一些;您可以创建require用于查看不同位置的“搜索器”,甚至可以更改内置搜索器的顺序,但这是一个高级主题。)

因此,只需将模块放在当前目录的 Lua 文件中就可以正常工作,并且package.path在调用require自己的模块之前进行调整可以涵盖您将遇到的大多数怪癖。

创建一个需要的模块

简单来说,模块就是可以存储在package.loaded. require一旦找到它,它将如何处理它,以便多次调用require只会搜索一次并始终返回相同的值。

传统的答案是“某物”是一个表,通常主要由可以调用的函数填充,偶尔还有值。该math模块是一个很好的例子:它提供了许多函数,比如sinand cos,以及有用的值math.piand math.huge

除了存储在表中之外,模块中的函数没有什么特别之处。像任何其他函数一样,它接受参数并返回零个或多个值。唯一真正的规则是模块不应更改或添加全局变量。

所以一个非常小的模块文件可以很简单:

return { 
  addtwo = function(a, b) return a+b end,
  subtwo = function(x) return x-2 end,
}
Run Code Online (Sandbox Code Playgroud)

如果存储为example.lua可以这样使用:

local example = require "example"
print(example.addtwo(2,2)) -- 4
print(example.subtwo(42))  -- 40
Run Code Online (Sandbox Code Playgroud)

更好的模块骨架

在大多数实际情况下,将所有代码粘贴在单个表声明中是行不通的。它不能很好地扩展,并且很难清楚地表达共享状态的函数之间的关系。

-- 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
Run Code Online (Sandbox Code Playgroud)

为什么不调用 module() 函数?

Lua 5.1 包含一个名为的标准函数,module()旨在用于模块实现的顶部。从来不需要使用它,并且很快就形成了共识,认为它不像希望的那样有用。它已被弃用。

因此,我上面展示的简单骨架没有使用它,并且可以移植到 Lua 5.1 以来的所有版本。