Cocos2d-x学习笔记:完全掌握Lua API与游戏项目开发 (未来书库)
上QQ阅读APP看书,第一时间看更新

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变量,第①行和第②行代码采用闭包表达式。