lua的闭包概念理解与介绍
来源:互联网 发布:pdf.js 跨域问题 编辑:程序博客网 时间:2024/06/11 06:49
转自http://blog.csdn.net/ym012/article/details/7208750
lua中的函数是一阶类型值(first-class value),定义函数就象创建普通类型值相同(只不过函数类型值的数据主要是一条条指令而已),所以在函数体中仍然能定义函数。假设函数f2定义在函数f1中,那么就称f2为f1的内嵌(inner)函数,f1为f2的外包(enclosing)函数,外包和内嵌都具有传递性,即f2的内嵌必然是f1的内嵌,而f1的外包也一定是f2的外包。内嵌函数能访问外包函数已创建的所有局部变量,这种特性便是所谓的词法定界(lexical scoping),而这些局部变量则称为该内嵌函数的外部局部变量(external local variable)或upvalue。试看如下代码:
- function f1(n)
- -- 函数参数也是局部变量
- local function f2()
- print(n) -- 引用外包函数的局部变量
- end
- return f2
- end
- g1 = f1(1979)
- g1() -- 打印出1979
- g2 = f1(500)
- g2() -- 打印出500
可为什么g2和g1的函数体相同(都是f1的内嵌函数f2的函数体),但打印值不同?这就涉及到一个相当重要的概念——闭包(closure)。事实上,Lua编译一个函数时,会为他生成一个原型(prototype),其中包含了函数体对应的虚拟机指令、函数用到的常量值(数,文本字符串等等)和一些调试信息。在运行时,每当Lua执行一个形如function...end 这样的表达式时,他就会创建一个新的数据对象,其中包含了相应函数原型的引用、环境(environment,用来查找全局变量的表)的引用及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。由此可见,函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。g1和g2的值严格来说不是函数而是闭包,并且是两个不相同的闭包,而每个闭包能保有自己的upvalue值,所以g1和g2打印出的结果当然就不相同了。
使用upvalue非常方便,但他们的语义也非常微妙,需要引起注意。比如将f1函数改成:
- function f1(n)
- local function f2()
- print(n)
- end
- n = n + 10
- return f2
- end
- g1 = f1(1979)
- g1() -- 打印出1989
upvalue还能为闭包之间提供一种数据共享的机制。试看下例:
- function Create(n)
- local function foo1()
- print(n)
- end
- local function foo2()
- n = n + 10
- end
- return foo1,foo2
- end
- f1,f2 = Create(1979)
- f1() -- 打印1979
- f2()
- f1() -- 打印1989
- f2()
- f1() -- 打印1999
闭包在创建之时其upvalue就已不在堆栈上的情况也有可能发生,这是因为内嵌函数能引用更外层外包函数的局部变量:
- function Test(n)
- local function foo()
- local function inner1()
- print(n)
- end
- local function inner2()
- n = n + 10
- end
- return inner1,inner2
- end
- return foo
- end
- t = Test(1979)
- f1,f2 = t()
- f1() -- 打印1979
- f2()
- f1() -- 打印1989
- g1,g2 = t()
- g1() -- 打印1989
- g2()
- g1() -- 打印1999
- f1() -- 打印1999
Lua将函数做为基本类型值并支持词法定界的特性使得语言具有强大的抽象能力。而透彻认识函数、闭包和upvalue将帮助程式员善用这种能力。
0 0
- lua的闭包概念理解与介绍
- lua的闭包概念理解与介绍
- lua 闭包的概念
- Lua闭包的理解
- 理解lua的闭包
- 理解闭包的概念
- 关于lua的闭包自我理解
- 深入浅出理解JavaScript的闭包概念
- 深入浅出理解JavaScript的闭包概念
- 深入浅出理解JavaScript的闭包概念
- Lua中的闭包理解
- lua闭包理解实例
- Lua学习之闭包概念
- 关于Lua的面向对象和闭包的理解
- Javascript闭包概念理解
- javascript理解闭包概念
- 闭包的概念、形式与应用
- 闭包的概念、形式与应用
- June 2014 market analysis nylon staple domestic spot market - Moncler Vest
- Blind expansion of brand advocates to intensify the main reason casual homogenization - 2014 Moncler
- Lavanya Sharan
- QTP的三种录制方式
- Git 常用命令详解(二)
- lua的闭包概念理解与介绍
- Front End Accessibility Development Guide
- Cocos2d-x格斗小游戏(四) 移动玩家精灵
- LeetCode刷题笔录Merge k Sorted Lists
- 暑期培训总结
- 易學原理總論
- 欢乐暑假线上编程比赛第四题:分配糖果
- WP8语音识别功能启动自己撰写的App
- window批处理-6 rem