当前位置: 首页 > news >正文

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

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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

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

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函数完成真正的计算。

转载于:https://my.oschina.net/u/223340/blog/293874

相关文章:

  • 用JSP实现的商城购物车模块
  • iOS开发应用学习笔记
  • iOS 真机测试流程
  • Hibernate(一)hibernate基本概念和体系结构
  • socketpair的使用
  • awk手册
  • 四六不分
  • Java 反射机制及Annotation
  • JavaScript超大整数加法
  • 多重和嵌套if
  • 曾国藩《挺经》卷七英才
  • OC关于NSDate类的方法和应用的总结!(全)
  • LIS问题---HDU1025 Constructing Roads In JGShining's Kingdom
  • xcode的ios工程目录结构复习
  • 基于运动特征的视频质量评价方法(基于H.264)
  • Javascript设计模式学习之Observer(观察者)模式
  • java小心机(3)| 浅析finalize()
  • Rancher-k8s加速安装文档
  • 程序员最讨厌的9句话,你可有补充?
  • 给Prometheus造假数据的方法
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 两列自适应布局方案整理
  • 如何设计一个微型分布式架构?
  • 为视图添加丝滑的水波纹
  • 线上 python http server profile 实践
  • 一文看透浏览器架构
  • Spring Batch JSON 支持
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • (C#)一个最简单的链表类
  • (二)pulsar安装在独立的docker中,python测试
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .bat文件调用java类的main方法
  • .gitignore文件---让git自动忽略指定文件
  • .NET Core Web APi类库如何内嵌运行?
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .net(C#)中String.Format如何使用
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • /run/containerd/containerd.sock connect: connection refused
  • @hook扩展分析
  • [ Linux ] Linux信号概述 信号的产生
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)
  • [C# 基础知识系列]专题十六:Linq介绍
  • [c]统计数字
  • [C++核心编程](四):类和对象——封装
  • [LeeCode]-Divide Two Integers 不用乘除的除法运算