首页 > 代码库 > lua闭合函数

lua闭合函数

若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量。这项特征称之为词法域。


function newCounter()
local i =0
return function()
  i = i+1
  return i
 end
end

 

c1 = newCounter()
print(c1())
print(c1())

c2 = newCounter()
print(c2())
print(c2())
print(c1())

 

一个closure就是一个函数加上该函数所需访问的所有非局部变量,如果再次调用newCounter,那么它会创建一个新的局部变量I.从而得到一个新的clousre。

从技术上讲,lua中只有closure,而不存在函数。因为,函数本身就是一种特殊的closure.不过只要不会引起混淆,仍将采用术语函数来指代closure。

在许多场合中,closure都是一种很有价值的工具。就像之前所看到的,它们可作为sort这类高阶函数的参数。closure对于那些创建其他函数的函数也很有价值。例如例如前面的newCounter。这种机制使Lua程序可以混合那些在函数式编程世界中久经考验的编程技术。另外,closure对于回调函数也很有用,这里有一个典型的例子,加上有一个传统的GUI工具包可以创建按钮,每个按钮都有一个回调函数。

 


function digitButton(digit)
return Button{label = tostring(digit),
        action=function()
              add_to_display(digit)
              end}
end

closure在另一种情况中也非常有用,例如在lua中函数式存储在普通变量中的,因此可以轻易地重新定义某些函数,甚至是重新定义那些预定义的函数。这也正是lua相当灵活的原因之一。通常当重新定义一个函数的时候,需要在新的实现中调用原来的那个函数。举例来说,假设要重新定义函数sin,使其参数能使用角度来代替原先的弧度,那么这个新函数就需要得转换它的实参,并调用原来的sin函数完成真正的计算,这段代码可能是这样的:


oldSin = math.sin
math.sin = function(x)
return oldSin(x*math.pi/180)
end


do
local oldSin = math.sin
local k = math.pi/180
math.sin = function(x)
    return oldSin(x*k)
  end
end

 

lua闭合函数