我眼中的“闭包”
- 接触闭包
-
接触编程以来,接触过好几种编程语言中都提到了闭包这个语言特性,Javascript,Ruby,Perl。最近在看关于Groovy的 时候也突出谈了闭包这个特性。Search了一下各大搜索引擎,发现Java里面也开始讨论要不要在后续版本里面加入闭包的特性了。由此可见闭包这个特 性,如何的吸引人。闲话少说,直接来看闭包吧!
下面的主要内容来源于各个搜索引擎。我只是整理了一下,找出一个最便于我自己理解的版本表述如下,可能在你看来这些理解是有失偏颇的,请你不要吝惜的告诉我。参考资料列表会附在后面,有兴趣可以直接读那些资料。
-
- 什么是闭包
- 闭包的概念,不同资料给出了好几种。
- 闭包:包含了自由(未绑定)变量的代码块,这些变量不是在这个代码块中或者任何全局上下文中定义的,而是定义代码块的环境中定义的。也就是下面两部分:
- 要执行的代码块(由于自由变量存在,相关变量引用没有释放)
- 为自由变量提供绑定的计算环境(作用域)
- 闭包:一种函数对象或者匿名函数,作为参数传递,可以动态的创建与返回
- 闭包:具有闭合作用域的匿名函数
- 第一层理解:闭包是具有特别作用域规则且可以作为参数的代码块
-
代码说明:
3.times {puts "Inside the times method."}
Results:
Inside the times method.
Inside the times method.
Inside the times method.
-
- 第二层理解:给上述的代码块扩展一个参数列表,使方法或函数可以与这个代码通讯
- 代码说明:
['lions', 'tigers', 'bears'].each {|item| puts item}
Results:
lions
tigers
bears
- 代码说明:
- 第三层理解:将这样的代码块作为参数传递
-
代码说明:
animals = ['lions', 'tigers', 'bears'].collect {|item| item.upcase}
puts animals.join(" and ") + " oh, my."
LIONS and TIGERS and BEARS oh, my.
-
- 第四层理解:定义代码块的环境的名称空间和使用它的函数之间的作用域本质上是一个作用域,即:作用域是闭合的
-
代码说明:
tax = 0.08
prices = [4.45, 6.34, 3.78]
tax_table = prices.collect {|price| {:price => price, :tax => price * tax}}
tax_table.collect {|item| puts "Price: #{item[:price]} Tax: #{item[:tax]}"}
Results:
Price: 4.45 Tax: 0.356
Price: 6.34 Tax: 0.5072
Price: 3.78 Tax: 0.3024
-
- 第一层理解:闭包是具有特别作用域规则且可以作为参数的代码块
- 按照SCIP定义:闭包就是一个携带有本地状态的函数
- 我对闭包的理解
- 闭包具有函数的性质
- 能完成一定的功能的代码块
- 能够预定义参数和引用作用域中的参数
- 能够在需要的地方被调用
- 闭包可以看成对象
- 能够作为参数传递
- 作用域的作用
- 作用域设定一个运行空间,但是作用域本身也很无赖,作用域知道自己能干什么,但是不知道具体要怎么做。只要作用域真正要用的时候,见到了闭包里面的代码块,作用域才算功德圆满了。这就是所谓“动态”的一种体现吧
- 作用域决定了闭包中代码块的使用方法
- 作用域决定了闭包中预设参数的本质,如参数的个数,类型
-
疑问:还没有搞清楚一个问题,在这里请教一下知道的
在闭包里面作用域提供的参数 是怎么和闭包里面预设的参数一一对应起来的呢?见下面代码
printMapClosure = {| key, value| puts key + "=" + value }
[ "yue" : "wu", "lane" : "burks", "sudha" : "saseethiaseeleethialeselan" ].each(printMapClosure)
result:yue=wu
lane=burks
sudha=saseethiaseeleethialeselan
我想知道为什么 key就对应yue,lane,sudha呢?而value就会对应wu,burks,sasee...呢?
不要告诉我是语义匹配这么高深的回答。呵呵 希望知道的人能给我说明白了怎么回事啊?指给我一些资料我也感激不尽啊。
-
- 作用域决定了闭包的最终处理结果
- 总结:闭包是一种被作用域限制的函数对象
- 闭包具有函数的性质
- 另附:未来Java可能会采用的两种闭包形式
- BGGA方案
-
说明:扩展了类型系统,引入了 function 类型,即函数都带有一个类型参数列表、返回类型和 throws 子句。
代码:完成求平方和
sumOfSquares = mapReduce(myBigCollection,
{ Double x => x * x },
{ Double x, Double y => x + y });
-
- CICE方案
-
说明:通过定义更简化的内部类来完成对闭包的支持
代码:完成求平方和
Double sumOfSquares = mapReduce(myBigCollection,
UnaryFunction<Double>(Double x) { return x*x; },
BinaryFunction<Double, Double>(Double x, Double y) { return x+y; });
-
- BGGA方案
- 附,参考资料
-
Java语言与实践:闭包之争 http://www.ibm.com/developerworks/cn/java/j-jtp04247.html
跨越边界:闭包 http://www.ibm.com/developerworks/cn/java/j-cb01097.html
MartinFowler说闭包
http://blog.csdn.net/limux/archive/2005/07/05/413911.aspx (中文)
http://martinfowler.com/bliki/Closure.html(英文)
-