转载请注明出处即可,无需经过我本人同意。
以下内容为网上的内容加上本人的理解,如有侵权,请通知本人删除文章。

闭包函数是什么:

首先看如下代码,你是否了解其真正的意义:

function test()local i=0return function()i=i+1return iend
enddoTest=test()
print(doTest())   --输出1
print(doTest())   --输出2

你可能有这样的疑问:
1. 调用test()返回的函数doTest()时,变量 i 的定义在哪?
2. test()中的i不是局部变量吗?为什么返回的函数还能调用。

如果你有这样的疑问,请接着往下看。
首先,了解几个概念:

词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界。而这些变量就被称为该内嵌函数的upvalue,upvalue实际指的是变量而不是值,这些变量可以在内部函数之间共享

闭包:通过调用含有一个内部函数加上该外部函数持有的外部局部变量(upvalue)的外部函数(外部函数就是工厂)产生的一个实例函数。

闭包组成:外部函数+外部函数创建的upvalue+内部函数(闭包函数)

如上面的函数test(),
test()就是外部函数
外部函数的局部变量local i=0就是upvalue(也叫做非局部变量,之所以叫做非局部变量,是因为此变量的作用域既不是局部变量的作用域,也不是全局变量的作用域。),
返回的函数就是内部函数

现在再回头看看原来的函数,我们知道了这种形式的函数叫做闭包函数。而test()中的局部变量i是内嵌函数的upvalue(非局部变量),且在内部函数中共享。

重复调用内部函数时,每一个调用都会记住上一次调用后的值,就是说第一次调用doTest()之后,i 的值已经是1了。

下面再看个例子

function test()local i=0return function()i=i+1return iend
enddoTest=test()
doAgain=test()
print(doTest())   --输出1
print(doTest())   --输出2print(doAgain())  --输出1
print(doAgain())  --输出2

可以看到,此时执行doAgain()时 i 值并没有在原来的基础上增加。

原因是:
doTest,doAgain是建立在同一个函数,同一个局部变量的不同实例上面的两个不同的闭包
调用一次test()就会产生一个新的闭包, 而闭包中的upvalue各自独立。所以不难解释为什么doAgain()的i 值为什么没有在原来的基础上增加了。

闭包函数有什么用:

在for in 的循环中需要使用到迭代器,而迭代器需要保留上一次调用的状态和下一次成功调用的状态,刚好可以使用闭包的机制来实现。

创建迭代器:

function list_iter(t)     --外包函数叫做工厂函数。local i=0local n=table.getn(t)return function()i=i+1if i<=n then return t[i] endendend
--[[这里的list_iter是一个工厂,每次调用都会产生一个新的闭包。该闭包内部包括了upvalue(t,i,n)。
因此每调用一次该函数产生的闭包,那么该闭包就会根据记录上一次的状态,以及返回list的下一个。]]

在while中使用:

--while中使用:
t={10,20,90}
iter=list_iter(t)  --调用迭代器产生一个闭包
while true do
--当闭包函数的i值已经等于n的值时,依然会执行闭包函数,此时返回的就是nil.
--如果没有下面的判断,while就会一直循环,并进入死循环。local element=iter()if element==nil then break endprint(element)
end

在泛型for使用


--泛型for使用:
t={10,0,29}
--这里的list_iter()工厂函数只会被调用一次产生一个闭包函数,
--后面的每一次迭代都是用该闭包函数,而不是工厂函数。
for element in list_iter(t) doprint(element)
end如果想要同时返回k,v值,需要修改工厂函数,如下所示:function list_iter(tb)local i = 0return function ()i = i + 1--如果没有下面这个判断,就会一直执行。--详情可以看我的另一篇博客,《Lua内容关于for循环的总结》if tb[i] == nil then  return nilend   return i,tb[i]end
end

闭包函数到底是什么?有什么用?相关推荐

  1. 闭包函数 装饰器 迭代器

    闭包函数 一.什么是闭包 闭包:闭是封闭(函数内部函数),包是包含(该内部函数对外部作用域而非全局作用域的变量的引用).闭包指的是:函数内部函数对外部作用域而非全局作用域的引用.简单的说闭包函数就是把 ...

  2. Python基础day4 函数对象、生成器 、装饰器、迭代器、闭包函数

    一.函数对象 正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松 ...

  3. python 函数进阶-闭包函数

    闭包函数 什么是闭包函数 如果内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,里面的内函数是闭包函数. # 外函数 outer def outer():# 外函数变量 numv ...

  4. JavaScript闭包函数箭头函数调用与执行

    一.标准的闭包函数 //一.标准的闭包函数 function A() {var i=0;++i;console.log('i : ' + i);return function b() {return ...

  5. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  6. 写的函数符号表里没有_你有没有想过,C语言 main 函数到底为啥这么写?

    但凡是学过C语言的人,都知道要先写main函数,然而很多时候我们看到的main函数却各有差异,这究竟是为啥?哪种是对的呢?今天我们就来聊聊main函数. 那么main函数一共有多少个版本呢? 1.ma ...

  7. php的闭包函数bingto_PHP 闭包那点事儿

    匿名函数 匿名函数,也叫闭包函数,说白了就是"没有名字的函数",和一般函数结构一样,只是少了函数名以及最后需要加上分号;. 注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视 ...

  8. python命名空间和闭包_Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】...

    本文实例讲述了Python函数基础用法.分享给大家供大家参考,具体如下: 一.什么是命名关键字参数? 格式: 在*后面参数都是命名关键字参数. 特点: 1.约束函数的调用者必须按照Kye=value的 ...

  9. char怎么比较_C语言的 main 函数到底怎么写才是对的?

    相信各位对C语言中的 main 函数大家都再熟悉不过了,这是你学习C语言首先就要学习的东西,但是我看过很多人写的代码包括我的一些读者在main函数的写法方面版本很多,今天就跟大家聊一聊main函数到底 ...

最新文章

  1. deepin中mysql数据库的连接_Python爬虫进阶教程(八):MySQL 数据库连接
  2. dhcp配置(个人)
  3. leetcode -eleven:Container With Most Water
  4. Linux下KVM虚拟机基本管理及常用命令(转)
  5. Linux CA证书与https讲解
  6. 和feign的区别_Feign的传参研究
  7. IDEA-Maven的Dependencies中出现红色波浪线
  8. c语言人机大战五子棋,五子棋人机大战将打响 祁观将与AI弈心五番棋对决
  9. 基于RFM模型的Kmeans聚类算法实现
  10. c语言中isupper用法,C语言中的isupper()函数
  11. 国产手机的18年历史
  12. JAVA实现时间换算
  13. 一行代码视频下载,so easy!
  14. Heapsort 代码 学习笔记 阳春三月版
  15. 修改php fpm监听端口,怎样修正php fpm监听端口_后端开发
  16. Codeforces - Serval and Parenthesis Sequence
  17. 阿里云服务器地域暂时无法办理经营性ICP许可证什么意思?
  18. centos 7.5 内核升级
  19. fractions -- 分数
  20. QT简单实验——计算器

热门文章

  1. php war包,War包 - java,ruby,net,css,php,C++,Python,
  2. Java程序员已经饱和了?这是个老话题了
  3. 自己制做立体影像! 揭秘你不知道的3D
  4. Prometheus+Clickhouse实现业务告警
  5. 顺丰2020年财报幕后:不可轻视的科技力量和新增长曲线
  6. ASP.NET使用文件流的方式下载文件
  7. 刘强东给高管兄弟降薪:2千多位总监工资打8折!同时拿出100亿保障基础员工住房
  8. Java使用zip4j进行文件压缩
  9. java计算机毕业设计疫情展示平台源码+数据库+系统+lw文档+部署
  10. base64文件流转换成pdf格式下载/打印,兼容IE浏览器