Lua 基础教程(十四)模块

79 阅读3分钟

Lua 基础教程(十四)模块

hudson 译 原文

什么是模块?

模块就像一个库,可以使用require加载,并有一个包含表的全局名称。模块可以由许多函数和变量组成。所有这些函数和变量都包装在表中,表充当命名空间。此外,行为良好的模块有必要的规定,根据需要可返回此表。

Lua模块的专长

在模块中使用表在许多方面非常有用,我们能够像操作任何其他Lua表一样操作模块。由于能够操作模块,因而能够提供其他语言需要特殊机制的额外功能。由于Lua中的这种自由模块机制,用户可以以多种方式调用Lua中的函数。其中一些如下所示。

-- Assuming we have a module printFormatter
-- Also printFormatter has a funtion simpleFormat(arg)
-- Method 1
require "printFormatter"
printFormatter.simpleFormat("test")

-- Method 2
local formatter = require "printFormatter"
formatter.simpleFormat("test")

-- Method 3
require "printFormatter"
local formatterFunction = printFormatter.simpleFormat
formatterFunction("test")

在上述示例代码中,可以看到Lua中的编程有多灵活,无需任何特殊的附加代码。

require函数

Lua提供了一个名为require的高级函数来加载所有必要的模块。它保持尽可能简单, 不需要模块提供有太多的信息就能够加载。require函数只是假设模块是定义一些值的代码块,这些值实际上是函数或者包含函数的表。

考虑下面一个简单的例子,一个模块有许多数学函数,称之为mymath,文件名是mymath.lua。文件内容如下:

local mymath =  {}

function mymath.add(a,b)
   print(a+b)
end

function mymath.sub(a,b)
   print(a-b)
end

function mymath.mul(a,b)
   print(a*b)
end

function mymath.div(a,b)
   print(a/b)
end

return mymath	

现在,要在另一个文件(例如moduletutorial.lua)中访问此Lua模块,需要使用以下代码片段:

mymathmodule = require("mymath")
mymathmodule.add(10,20)
mymathmodule.sub(30,20)
mymathmodule.mul(10,20)
mymathmodule.div(30,20)

为了运行此代码,我需要将两个Lua文件放在同一个目录中,或者,也可以将模块文件放在软件包路径中,后者需要额外的设置。

运行上述程序时,将得到以下输出:

30
10
200
1.5

几点注意事项

  • 将模块和需要运行的文件都放在同一个目录中。
  • 模块名称及其文件名应相同。
  • 最佳实践是,require函数返回模块 ,因此该模块最好如上所述方式实现,即使其他地方也可以找到其他类型的实现。

实现模块的旧方法

现在以旧的方式重写相同的示例,该示例使用package.seeall类型实现模块,是 Lua 5.1和5.0版本中使用的方法。 Mymath模块如下所示:

module("mymath", package.seeall)

function mymath.add(a,b)
   print(a+b)
end

function mymath.sub(a,b)
   print(a-b)
end

function mymath.mul(a,b)
   print(a*b)
end

function mymath.div(a,b)
   print(a/b)
end

Moduletutorial.lua中模块的使用情况如下所示:

require("mymath")
mymath.add(10,20)
mymath.sub(30,20)
mymath.mul(10,20)
mymath.div(30,20)

运行上述代码时, 会看到相同的输出。尽管如此,建议不要使用此方法实现模块,因为它不太安全。许多使用Lua进行编程的SDK(如Corona SDK)已弃用这种方法。