Lua中函数与面向对象编程的基础知识整理

2019-10-28 18:47:38 来源:易采站长站 作者:王旭

函数
1. 基础知识
调用函数都需要写圆括号,即使没有参数,但有一种特殊例外:函数若只有一个参数且参数是字面字符串或table构造式,则圆括号可有可无,如dofile 'a.lua',f{x=10, y=20}。

Lua为面向对象式的调用提供冒号操作符的特殊语法,如o.foo(o, x)等价于o:foo(x)。和Javascript类似,调用函数时提供的实参数量可以与形参数量不同,若实参多了则舍弃,不足则多余的形参初始化为nil。

1.1 多重返回值

Lua允许函数返回多个结果,函数返回如return max, index,接收如s, e = string.find("hello Lua world", "Lua")。如果一个函数调用不是一系列表达式的最后一个元素,则只产生一个值:

function foo() return "a", "b" end
x, y = foo(), 20  -- x="a", y=20(foo的第二个返回值被丢弃)
print(foo() .. "x")  -- 输出ax,这是因为当函数出现在一个表达式中时,Lua会将其返回值数量调整为1

另外,只有当一个函数调用作为最后一个元素时,返回值才不会被调整,在其他位置都会被调整为1个,如t = {foo2()}则t={“a”, “b”},t = {foo2(), 4}则t={“a”, 4}。

特殊函数unpack接受一个数组作为参数,并从下标1开始返回该数组的所有元素,如a, b = unpack({10, 20, 30}),则30被丢弃。unpack的一项重要用途体现在“泛型调用”机制中。

1.2 变长参数

函数参数表中3个点(…)表示该函数可接受不同数量的实参。在Lua 5.0中,没有提供“…”表达式,如果要遍历变长参数,可以访问函数内隐含的局部变量arg。如果还有固定参数,则必须放在变长参数之前。

2. 高级主题
2.1 closure闭合函数

和Javascript的闭包基本是一个东西,此处不再赘述。从技术上说,Lua中只有closure,而不存在“函数”,因为函数本身就是一种特殊的closure。closure的应用很广泛,如用于高阶函数的参数、为GUI工具包创建回调、重定义函数并在新实现中调用旧实现、创建“沙盒”安全运行环境等等。

2.2 非全局的函数

大部分Lua库都采用了将函数存储在table中的机制(如io.read,math.sin),例如下面采用了三种方式来定义table的成员函数:

MathLib = {
  plus = function(x, y) return x + y end
}
MathLib.minus = function(x, y) return x - y end
function MathLib.multiply(x, y) return x * y end

局部函数的定义:

local f = function(<参数>) <函数体> end
local function f(<参数>) <函数体> end -- Lua提供的语法糖

**注意如果定义递归函数,不能使用上面第一种定义方式(因为在函数体调用f时,f尚未定义完毕),使用第二种“语法糖”则没问题;或者使用“前向声明”,先local f再f = function ...这样定义。

微信扫一扫

易采站长站微信账号