Lua程序设计 closure(闭合函数)

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

        假设有一个学生姓名的列表和一个对应于每一个姓名的年级列表,须要根据每一个学生的年纪来对他们的姓名进行排序。lua

names = {"Peter", "Paul", "Mary"}
grades = {Mary = 10, Paul = 7, Peter = 8}
table.sort(names, function(n1, n2)
      return grades[n1, n2] --比较年级
     end) 
     
如今,假设要单首创建一个函数来作这项工做:
function sortbygrade(names,grades)
 table.sort(names, function(n1, n2)
     return grades[n1] > grade[n2]  --比较年级
    end)
end
注意:上例中传递给sort的匿名函数能够访问参数grades,而grades是外部函数sortbygrade的局部变量。在这个匿名函数的内部,grades既不是全局变量也不是局部变量,将其称为一个“非局部的变量”。
由于函数是“第一类值”的缘由,因此容许这样访问。

 

function newCounter()
local i = 0
return function ()  --匿名函数
    i = i + 1
    return i
    end
end 

c1 = newCounter()
print(c1())  -->1
print(c1())  -->2
   这段代码中,匿名函数访问了一个“非局部的变量”i,该变量用于保持一个计数器。初看上去,因为建立变量i的函数已经返回,因此以后每次调用匿名函数时,i都应是已超出了做用范围的,可是,Lua会以closure的概念来处理。
   简单的讲,一个closure就是一个函数加上该函数所需访问的全部“非局部变量”。若是再次调用newCounter,那么它会建立一个新的局部变量i,从而也将获得一个新的closure。
   
  c2 = newCounter()
  print(c2())  --- >1
  print(c1())  --- >3
  print(c2()) --- >2
  所以,c1和c2是同一个函数所建立的两个不一样的closure,它们各自拥有局部变量i的独立实例。

         从技术上讲,Lua中只有closure而不存在“函数”,由于函数自己就是一种特殊的closure【closure:指一个函数以及一系列这个函数会访问到“非局部的变量”,所以若一个closure没有那些会访问的“非局部变量”,那他就是一个传统概念中的“函数”】。spa

       Lua中函数是存储在普通变量中的,所以能够轻易地从新定义某些函数,甚至是从新定义那些预约义的函数。一般当从新定义一个函数的时候,须要在新的实现中调用原来的那个函数。code

 oldSin = math.sin
math.sin = function(x) return oldSin(x * math.pi/180) end
假设要从新定义函数sin,使其参数能使用角度来代替原先的弧度。这个新函数就必须得转换它的实参,并调用原来的sin函数完成真正的计算。
相关文章
相关标签/搜索