在其他文件上访问Lua函数

时间:2016-01-06 23:38:18

标签: lua

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

require "subsystem.lua"

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

我需要修改配置文件吗?它在哪里?

3 个答案:

答案 0 :(得分:3)

您需要做的是返回一个包含您要在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()

您可能需要查看Modules tutorial了解详细信息。

答案 1 :(得分:3)

需要模块

require函数在一系列位置查找模块。通过调整全局表package中的字段,可以对广泛的地点列表进行广泛的自定义。

了解查找模块时使用的位数和名称的最简单方法是查看require失败时生成的错误消息。例如,在我的电脑上,Lua 5.1说:

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将用模块名替换每个?,然后尝试读取该文件。第一个成功使用。

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

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

创建要求

的模块

最简单的是,模块只能存储在package.loaded中。 require一旦找到,require将对其执行的操作是什么,因此对math的多次调用只会搜索一次并始终返回相同的值。

传统的答案是将“某事”作为一个表,通常主要由可以调用的函数填充,偶尔也有值。 sin模块就是一个很好的例子:它提供了许多函数,如cosmath.pi,以及有用的值math.hugereturn { addtwo = function(a, b) return a+b end, subtwo = function(x) return x-2 end, }

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

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

example.lua

如果存储为local example = require "example" print(example.addtwo(2,2)) -- 4 print(example.subtwo(42)) -- 40 ,可以像这样使用:

-- 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

更好的模块骨架

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

module()

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

Lua 5.1包含一个名为return sqLiteDatabase.update(AdminContact.Question.TABLE_QUIZ, contentValues, AdminContact.Question.ID=?,newString[] {rowId});的标准函数,旨在用于模块实现的顶部。它的使用从来没有被要求,并且很快形成了一个共识,它没有像希望的那样有用。它已被弃用。

因此,上面显示的简单骨架不使用它,并且从5.1开始便可移植到所有版本的Lua。

答案 2 :(得分:1)

您可能希望使用dofile代替require

dofile接受包含路径的文件名。

require接受模块名称并使用Lua搜索路径。