lua中的闭包(closure或者匿名函数)的作用
闭包和upvalue
lua构建一个新的函数时, 会创建一个函数对象, 其中包含了函数本身的原型还有函数使用到的外部变量或者常量. 当这个新的函数处于某个函数内部, 我们将这个对象称之为闭包, 它所引用的外部函数的局部变量叫做upvalue.
下面是一个例子:
function f1(n)local upvalue = "hello"local f2 = function()print(upvalue .. " " .. n)endreturn f2
endg1 = f1(500)
g1()
print(g1)g2 = f1(1500)
g2()
print(g2)$ luajit copy.lua
$ hello 500
$ function: 0x00921ae0
$ hello 1500
$ function: 0x00926f28
每次调用f1将生成一个以f2为函数原型, 加上两个upvalue值(n, upvalue)的新函数(闭包). 每个新的闭包保持同一函数原型, 分别保存不同的upvalue. 严格来说, 闭包属于动态的概念, 是在程序运行阶段确定的.
upvalue值的作用域
upvalue实际上是闭包的外部函数的局部变量, 存在于外部函数的堆栈中, 在外部函数的执行过程中, 闭包通过访问外部函数堆栈的upvalue引用来访问upvalue, 一旦外部函数的调用过程完毕, 函数的堆栈被清空, upvalue也会被清除, 此时闭包会将upvalue复制到自己的函数堆栈中以便使用. 外部函数(也可以是闭包)执行完毕之前, 内部的闭包和其子闭包使用的都是外部函数堆栈中的那一份, 任何修改都会影响所有的函数(外部函数, 闭包和其子闭包), 当外部函数执行完毕后, 内部的闭包和其子闭包使用的是内部闭包从外部函数复制的那一份, 可以以此类推到最里层的闭包. 下面举例说明.
function f1(n)local upvalue = "hello"local f0 = function()local f2 = function()n = n * 2print(upvalue .. " f2 " .. n)endlocal f3 = function()print(upvalue .. " f3 " .. n)endprint(upvalue .. " f0 " .. n)return f2, f3endg1, g2 = f0()g1()g2()print(upvalue .. " f1 " .. n)return f0
endg0 = f1(500)$ luajit copy.lua
$ hello f0 500
$ hello f2 1000
$ hello f3 1000
$ hello f1 1000
f1是外部函数, n是其内部变量, 也是内部的f2, f3形成的闭包的upvalue. 要注意的是, 每次进入f1时, 变量n都是不同的, 生成的闭包共享和保存的是当次进入外部函数时的局部变量.
闭包的作用
闭包的主要作用有两个, 一是简洁, 不需要在不使用时生成对象, 也不需要函数名, 二是可以捕获外部变量形成不同的调用环境. 从其名称可以看出来, 闭包的最主要作用是后者, 即可以捕获外部变量.
下面举例说明:
function f1()local i = 0return function()i = i + 1return iend
endg1 = f1()
g2 = f1()print("g1 " .. g1())
print("g1 " .. g1())print("------------------------")print("g2 " .. g2())
print("g2 " .. g2())$ luajit test.lua
> g1 1
> g1 2
> ------------------------
> g2 1
> g2 2
每次调用f1时会生成不同的局部变量i(值为函数定义时的初始值), 此时闭包将i保存和使用, 与另外的闭包独立开来. g1和g2共享一份函数定义和upvalue初始值, 但是调用环境独立.
这种特性最典型的使用场景是迭代器:
function f1(t)local i = 0return function()i = i + 1return t[i]end
endt = {"111", "heell", 5, 6, "3333"}
for e in f1(t) doprint(e)
end$ luajit test.lua
> 111
> heell
> 5
> 6
> 3333
lua中的闭包(closure或者匿名函数)的作用相关推荐
- 两个函数彻底理解Lua中的闭包
本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: 1 --[[************************************ ...
- colsure php_PHP_PHP中Closure类的使用方法及详解,Closure,匿名函数,又称为Anonym - phpStudy...
PHP中Closure类的使用方法及详解 Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的.匿名函数就是没有定义名字的函数.这点牢牢记住就能理解匿名函 ...
- Rust Closure 闭包解析(匿名函数)
Rust Closure 闭包解析(匿名函数) 文章目录 Rust Closure 闭包解析(匿名函数) 正文 1. 简单闭包 - 纯粹的匿名函数 2. 捕获上下文 & FnOnce.FnMu ...
- 匿名函数php作用,深入理解PHP中的匿名函数
匿名函数的作用就是扩大函数的使用功能,在PHP(PHP培训 php教程 ) 5.3以前,传递Callback的方式,我们只有俩种选择: ◆字符串的函数名 ◆使用create_function的返回 在 ...
- php debug_print_backtrace,php中debug_backtrace、debug_print_backtrace和匿名函数用法实例
本文实例讲述了php中debug_backtrace.debug_print_backtrace和匿名函数用法.分享给大家供大家参考.具体分析如下: debug_print_backtrace() 是 ...
- python中的闭包(closure)
背景 本文尝试介绍Python中的闭包(closure),包括闭包是什么? 为什么要使用闭包?如何使用闭包? 嵌套函数及非局部变量 在介绍闭包之前,需要先明白什么是嵌套函数和非局部变量.在一个函数(f ...
- js中的匿名函数的作用以及用法讲解
匿名函数顾名思义指的是没有名字的函数,在实际开发中使用的频率非常高!也是学好JS的重点. 释义:匿名函数,就是没有实际名字的函数. 小试牛刀,首先我们声明一个普通函数: //声明一个普通函数,函数的名 ...
- python中匿名函数的作用_什么是Python中的匿名函数
匿名函数 lambda x , y : x+y 1.匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的. 2.匿名函数的参数规则.作用域关系与有名函数是一样的. 3.匿名函数的函数体通常应该 ...
- Closure 代表匿名函数的类
Closure 用于获取并使用匿名函数.将匿名函数绑定到具体的类,从而实现对匿名函数的更多控制. 举个例子: #不绑定,直接使用匿名函数$f = function ($var){return $var ...
最新文章
- 【原创】MyEclipse反编译添加jadclipse_3.3.0 曲折的完美解决
- Parallels Desktop 16 Win11虚拟机将继续正常运作,但将无法连接网络
- C#中几种换行符,不同操作系统各不相同【转】
- 【OpenCV】IplImage类型图像ROI矩形区域的快速获取
- 通过google app engine 在google cloud 部署支持quic的Java web 应用(多种方式)
- path:path在路由中的使用
- python经典算法--------冒泡排序
- 11月16日云栖精选夜读:阿里云 oss JavaScript客户端签名文件上传 vue2.0
- tesseract 配置文件
- sqlserver 存储过程 分页搜索查询
- python二分法代码_Python的算法之二分法
- hypermesh10的安装
- SQLite快速入门
- Codeforces #123D: 后缀数组+单调栈
- 轻松学习Linux之入门篇
- mysql索引失效的几种情况
- iPhoneXSM屏幕适配、 各机型的逻辑分辨率
- Oracle:Locked by transaction: console [表名]
- snaker并行任务示例
- 无线射频专题《射频合规,ISM频段》
热门文章
- Java之智力题【史上最全】
- midas显示代理服务器错误,[转载]在使用桥博、midas的时候经常会遇到的问题
- 豆瓣Top250电影爬虫
- 一般线性模型、混合线性模型、广义线性模型
- [笔记] JSP 与 JSPX 语法差异对比 [草稿,待续]
- 爬虫逆向基础,认识 SM1-SM9、ZUC 国密算法
- vs2013 调试出现error C1083无法打开包括的文件
- (一)SQL语言_数据库_学习笔记
- 戴尔G3 3590 Opencore引导Mac 11.5.1 BigSur 完美驱动
- 业务中立_网络中立性的终结了吗?