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

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

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

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没有那些会访问的“非局部变量”,那他就是一个传统概念中的“函数”】。

Lua中函数是存储在普通变量中的,因此可以轻易地重新定义某些函数,甚至是重新定义那些预定义的函数。通常当重新定义一个函数的时候,需要在新的实现中调用原来的那个函数。

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

Lua程序设计 closure(闭合函数),布布扣,bubuko.com

时间: 2024-08-03 15:40:35

Lua程序设计 closure(闭合函数)的相关文章

lua中的closure(闭合函数)

若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数的局部变量. function newCounter() local i = 0 return function()----匿名函数 i = i + 1 return i end end c1 = newCounter() c2 = nweCounter() print(c1())---->1 print(c1())---->2 print(c2())---->1 print(c1())---->3 print

Lua程序设计之深入函数

先看一个函数: function derivative(f,delta) delta = delta or1e-4 return function(x) return (f(x+delta)-f(x))/delta end end 对特定的函数f调用derivative(f)将(近似地)返回其导数,例如 c=derivative(math.sin) print(math.cos(10),c(10))  --c(10)这样的调用相当于derivative(math.sin)(10) 这个例子最让我

《lua程序设计 第二版》 学习笔记6 -------- 深入函数

-- 第6章 深入函数 -- 函数是一种"第一类值",他们具有特定的"词法域" -- "第一类值":与其他传统类型的值具有相同的权利.例如:存储到变量/table中,作为实参传递给函数或者作为其他函数的返回值 -- "词法域":一个函数可以嵌套在另一个函数中,内部函数可以反问外部函数的变量. local function testFun(x) return 2 * x end -- 函数定义方式1 local testFun

Lua中的closure(闭合函数)

词法域:若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量,这项特征称之为“词法域”. 例:假设有一个学生姓名的列表和一个对应于没个姓名的年级列表,需要根据每个学生的年级来对他们的姓名进行排序(由高到低).可以这么做: names = {"Peter", "Paul", "Mary"} grades = {Mary = 10, Paul = 7, Peter = 8} table.sort(names, func

Lua程序设计 迭代器与closure

所谓"迭代器"就是一种可以遍历一种集合中所有元素的机制.在Lua中,通常将迭代器表示为函数.每调用一次函数,即返回集合中的"下一个"元素. 每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置及如何步进到下一个位置.在Lua中,closure对于这类任务提供了极佳的支持,一个closure就是一种可以访问其外部嵌套环境中的局部变量的函数.对于closure而言,这些变量就可用于在成功调用之间保持状态值,从而使closure可以记住它在一次遍历中所

第六章 深入理解函数 Lua程序设计笔记

--第六章 深入理解函数Lua中函数是"第一类值",与其他传统类型有相同的权利:可以储存到变量或table中,可以作为函数实参传递,还可以作为函数的返回值. 函数的标准定义: foo = function(x) return x*2 end 一个函数定义实际上就是一条赋值语句,这条语句创建了一种类型为"函数"的值,并将这个值赋予一个变量. --6.1closure(闭合函数) function newCounter() local i = 0 return func

lua闭合函数

function count( ... ) local i = 0 return function( ... ) i = i+ 1 return i end end local func = count(...) print(func()) print(func()) print(func()) 结果如下: 1 2 3 [Finished in 0.1s] lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”. 如上所示:count()函数返回了另一个函数,而这个函数使用了count

Lua程序设计 深入函数01

在Lua中,函数是一种"第一类值":表示在Lua中的函数与其他传统类型的值(例如:数字和字符串)是一样的,可以存储到变量(全局,局部均可)或table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值. "词法域":指一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数中的变量. Lua中的函数与所有其他值一样都是匿名的,当讨论一个函数时,实际上是在讨论一个持有某函数的变量.这与变量持有各种值一个道理,可以以多种方式来操作这些变量. a = {p = 

Lua程序设计 函数 正确的尾调用

Lua中的"尾调用"就是一种类似于goto的函数调用,当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条"尾调用".[一个函数在调用完另一个函数之后,是否就无其他事情需要做了] function f(x) return g(x) end   也就是说,当f调用完g之后,f所代表的整个函数的调用才算执行完成也就无其他事情可做了.因此,这种情况中,程序就不需要返回那个"尾调用"所在的函数了. 所以在"尾调用"之后,程序也