提出了向Java语言中添加闭包的三项主要建议:
我的问题是:
发布于 2009-11-25 19:04:15
这篇IBM论文给出了BGGA和CICE语法区别的很好例子:
BGGA提案
BGGA提案创建了函数类型的概念,其中一个函数有一个类型化的参数列表、一个返回类型和一个抛出子句。在BGGA建议中,平方和代码如清单9所示:
清单9。用BGGA闭包语法计算平方和
sumOfSquares = mapReduce(myBigCollection,
{ Double x => x * x },
{ Double x, Double y => x + y });=>符号左边大括号中的代码标识参数的名称和类型;右边的代码表示正在定义的匿名函数的实现。此代码可以引用块中定义的局部变量、闭包的参数或创建闭包的作用域中的变量。
在BGGA建议中,可以声明变量、方法参数和作为函数类型的方法返回值。您可以在期望单个抽象方法类的实例(如Runnable或Callable)的任何上下文中提供闭包;对于匿名类型的闭包,提供了invoke()方法,以便使用指定的参数列表调用它们。
BGGA建议的主要目标之一是允许程序员创建类似于控制结构的方法。因此,BGGA还提出了一些语法糖,允许您调用那些接受闭包的方法,就好像它们是新的关键字一样,这样您就可以创建像withLock()或forEach()这样的方法,并像调用控制原语一样调用它们。清单10显示了如何在BGGA提案下定义withLock()方法;清单11和清单12展示了如何使用标准表单和“控制构造”表单调用该方法:
清单10。在BGGA闭包方案下编写withLock()方法
public static <T,throws E extends Exception>
T withLock(Lock lock, {=>T throws E} block) throws E {
lock.lock();
try {
return block.invoke();
} finally {
lock.unlock();
}
}清单10中的withLock()方法接受一个锁和一个闭包。闭包的返回类型和抛出子句是泛型参数;编译器中的类型推断通常允许在不指定T和E值的情况下调用它,如清单11和清单12所示:
清单11。调用withLock()
withLock(lock, {=>
System.out.println("hello");
});清单12。使用控件构造速记调用withLock()
withLock(lock) {
System.out.println("hello");
}与泛型一样,BGGA建议下的闭包的大部分复杂性由库创建者承担;使用接受闭包的库方法要简单得多。
BGGA的建议还可以修复在试图使用内部类实例获得闭包的好处时出现的许多透明度错误。例如,返回、中断和这在代码块中的语义与表示相同代码块的可运行(或其他内部类实例)中的语义不同。在迁移代码以利用通用算法时,这些非透明性元素可能导致混淆。
CICE提案
CICE提案是一个简单的建议,它解决了实例化内部类实例太麻烦的问题。它不是创建函数类型的概念,而是创建一个更紧凑的语法,用于使用单个抽象方法(例如Runnable、可调用或比较器)实例化内部类的实例。
清单13显示了CICE下的平方代码的总和。它明确了UnaryFunction ()使用的mapReduce和BinaryFunction类型。mapReduce()的参数是从UnaryFunction和BinaryFunction派生的匿名类;语法简单地减少了与创建匿名实例相关的大量冗余。
清单13。CICE闭包方案下的平方码和
Double sumOfSquares = mapReduce(myBigCollection,
UnaryFunction<Double>(Double x) { return x*x; },
BinaryFunction<Double, Double>(Double x, Double y) { return x+y; });因为表示传递给mapReduce()的函数的对象是普通的匿名类实例,它们的主体可以引用在封闭作用域中定义的变量;清单13和清单7中的方法之间唯一的区别是语法的冗长。
发布于 2009-11-25 19:15:55
“欢乐时光”(Joda Time)的斯蒂芬·柯尔伯恩( Stephen )最近在写一篇关于闭包建议的简短摘要上成名。
https://stackoverflow.com/questions/1799196
复制相似问题