返回信息流费了半天劲,有点明白意思了,
好像都是出现在,把函数看成是对象的语言当中。
个人理解和代码模板有点类似,而且这个模板还是可以new出来的。
这个和C++里面的函数对象有很大区别么?
大牛们,请砸砖
=。=
这是一条镜像帖。来源:北邮人论坛 / soft-design / #29713同步于 2008/9/6
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
不知道发在哪边合适,关于闭包
ericyosho
2008/9/6镜像同步19 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
这个定义我明白,关键是怎么转化为我们熟悉的代码语言。
函数好理解,那附带的运行环境是什么,它们怎么转换成具体的代码语言呢?
个人感觉也就是和这个函数在同一个层面上的一些 “符号”。
那比较直观的理解就是,一个嵌套函数,或者一个嵌套对象。
“函数”指的就是内部的那个;外边的那个整体就叫做“闭包”?
还有,按照严格的定义来说,
闭包=功能执行本身+依赖的执行环境
我能不能说,一个功能函数加一堆的状态变量,共同组成了一个广义上的闭包呢?
我能不能说,其实所有的能被称之为 “系统” 的东西,包括操作系统,具体的某一种语言的实现,代码中的每一个对象,都可以被叫做闭包呢?
【 在 ericyosho 的大作中提到: 】
: 这个定义我明白,关键是怎么转化为我们熟悉的代码语言。
: 函数好理解,那附带的运行环境是什么,它们怎么转换成具体的代码语言呢?
: 个人感觉也就是和这个函数在同一个层面上的一些 “符号”。
: ...................
我用C#改写了一段SICP 2.1.3的代码,用函数闭包实现一个类似于STL的Pair,也就是点对
delegate int Pair(int m);//声明一个委托,类似于函数指针
Pair CreatePair(int x,int y)
{
return delegate(int m) //这里构造一个匿名函数,并返回它
{
if (m == 0)
return x; //这里将CeatePair的参数x带出外面,也就是携带了创建匿名函数的时候的上下文环境
if (m == 1)
return y;//同上
throw new Exception("输入的是无效参数值,请输入1或者0");
};
}
int GetFirst(Pair pair)//获取Pair的第一个数
{
return pair(0);
}
int GetSecond(Pair pair)//获取Pair的第二个数
{
return pair(1);
}
呃,说实话,没看出和函数对象的差别。
我自己的总结:
只要符合两个特性就能叫做闭包:
1. 内部类使用超出自己范围以外的东西
2. 代码作为对象,可以赋给其他值,以备使用
其实,好像还有一个更加简单的,
使用了函数指针的就是闭包。(函数对象其实就是函数引用,也就是函数指针。)
【 在 ericyosho 的大作中提到: 】
: 呃,说实话,没看出和函数对象的差别。
: 我自己的总结:
: 只要符合两个特性就能叫做闭包:
: ...................
恩,差不多。
不过函数对象和C++函数指针并不一样,因为函数对象首先你要创建一个对象,在创建的时候你给它传了一些参数,设置了一些状态.。而C++函数指针你就只能引用一个已经存在的函数,它并不携带任何状态或者所谓的携带上下文环境。
函数对象其实可以看成是显式的手工的lambda lifting,而C#的函数闭包的lambda lifting是由编译器来做的,你反编译可以看得到它是怎么做的。但其它一些语言比如Javascript的闭包貌似还不一样,它好像是用static link来做的。如果要深入了解这些细节,推荐你看一本书《程序设计语言――实践之路》
至于你如何定义闭包那就是你的自由了,只要让别人明白你的意思就OK
对象是附有行为的数据,而闭包是附有数据的行为
【 在 ericyosho (ericyosho) 的大作中提到: 】
: 费了半天劲,有点明白意思了,
: 好像都是出现在,把函数看成是对象的语言当中。
: 个人理解和代码模板有点类似,而且这个模板还是可以new出来的。
: ...................
http://eclipsezone.com/eclipse/forums/t86911.html
这个blog讲得很清楚。
引用了free variable的lambda表达式之于closure的关系,就如同构造函数之于对象实例的关系。
lambda表达式本身不是closure,而是lambda表达式被计算时,产生了一个closure的“对象”。
那继续有一个问题,
如果一个lambda表达式没有引用外部的free variable。
那么在运行这个lambda表达式的时候,还会不会产生closure呢?