2.11 闭包函数
一门计算语言要支持闭包的前提是:
□ 支持函数类型,能够将函数作出参数或返回值传递;
□ 支持函数嵌套;
这两个前提Lua都是满足的,在Lua中可以在一个函数中定义另一个函数,函数还可以作为一个“值”进行传递,即作为函数的参数或作为返回值返回。
2.11.1 嵌套函数
在此之前我们定义的函数都是全局函数,它们定义在全局作用域中,我们也可以把函数定义在另外的函数体中,称作嵌套函数。
下面看一个示例:
function calculate(opr, a, b) ① --定义+函数 function add(a, b) ② return a + b end --定义-函数 function sub(a, b) ③ return a - b end local result if opr =="+"then result = add(a, b) ④ else result = sub(a, b) ⑤ end return result ⑥ end local res1 = calculate("+",10,5) ⑦ print("10 + 5 ="..res1) local res2 = calculate("-",10,5) ⑧ print("10 - 5 ="..res2)
上述代码第①行定义calculate函数,它的作用是根据运算符进行数学计算,它的参数opr是运算符,参数a和b是要计算数值。在calculate函数体内,第②行定义了嵌套函数add,对两个参数进行加法运算。第③行定义了嵌套函数sub,对两个参数进行减法运算。第④行代码是在运算符为“+”号情况下使用add函数进行计算,并将结果赋值给result。第⑤行代码是在运算符为“-”号情况下使用sub函数进行计算,并将结果赋值给result。第⑥行代码是返回函数变量result。
第⑦行代码调用calculate函数进行加法运算。第⑧行代码调用calculate函数进行减法运算。
程序运行结果:
10 + 5 = 15 10 - 5 = 5
在函数嵌套中,默认情况下嵌套函数则作用域是在外函数体内。
2.11.2 返回函数
我们可以把函数作为另一个函数的返回类型使用。下面看一个示例:
--定义计算长方形面积函数 function rectangleArea(width, height) local area = width* height return area end --定义计算三角形面积函数 function triangleArea(bottom, height) local area = 0.5 * bottom * height return area end function getArea(type) ① local returnFunction ② if type == "rect"then --rect 表示长方形 returnFunction= rectangleArea ③ else --tria 表示三角形 returnFunction= triangleArea ④ end return returnFunction ⑤ end --获得计算三角形面积函数 local area = getArea("tria") ⑥ print("底 10 高 13,三角形面积:"..area(10,15)) ⑦ --获得计算长方形面积函数 local area = getArea("rect") ⑧ print("宽 10 高 15,计算长方形面积:"..area(10,15)) ⑨
上述代码第①行定义函数getArea(type),其他行是返回一个函数。第②行代码是声明returnFunction变量保存要返回的函数名。第③行代码是在类型type为rect(即长方形)情况下,把2.11.1节定义的rectangleArea函数名赋值给returnFunction变量。第④行代码是在类型type为tria(即三角形)的情况下,把2.11.1节定义的triangleArea函数名赋值给returnFunction变量。第⑤行代码是将returnFunction变量返回。
第⑥行和第⑧行代码是调用函数getArea,返回值area是函数类型。我们在第⑦行和第⑨行代码中的area(10,15)是调用函数。
上述代码运行结果如下:
底10高13,三角形面积:75.0 宽10高15,计算长方形面积:150.0
2.11.3 使用闭包表达式
我们还可以采用匿名函数形式的闭包表达式。修改2.11.2节的示例代码如下:
function getArea(type) local returnFunction if type == "rect"then --rect 表示长方形 returnFunction= function(width, height) ① local area = width* height return area end else --tria 表示三角形 returnFunction= function(bottom, height) ② local area = 0.5 * bottom * height return area end end return returnFunction end --获得计算三角形面积函数 local area = getArea("tria") print("底 10 高 13,三角形面积:"..area(10,15)) --获得计算长方形面积函数 local area = getArea("rect") print("宽 10 高 15,计算长方形面积:"..area(10,15))
采用匿名函数赋值给returnFunction变量,第①行和第②行代码采用闭包表达式。