什么是闭包

闭包的概念,不同资料给出了好几种。

闭包:包含了自由(未绑定)变量的代码块,这些变量不是在这个代码块中或者任何全局上下文中定义的,而是定义代码块的环境中定义的。也就是下面两部分:

要执行的代码块(由于自由变量存在,相关变量引用没有释放)
为自由变量提供绑定的计算环境(作用域)

闭包:一种函数对象或者匿名函数,作为参数传递,可以动态的创建与返回

闭包:具有闭合作用域的匿名函数

第一层理解:闭包是具有特别作用域规则且可以作为参数的代码块

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; });