Groovy探索之闭包 四
前面我都有数次提到过,说闭包较之于方法或者内部类都显得格外的灵活,前面的《Groovy探索之闭包》也都是围绕着闭包灵活的这一特性来阐述的。今天将要提到的是闭包灵活性的另外一个方面——curry方法。
为什么说闭包的curry方法是闭包灵活性的又一个方面,我不想泛泛而谈,下面还是从几个例子说起。
假设我们有一个方法来计算成方:
def
static
cal(
int
x,
int
y)
{
return
x**y
}
现在,我们要对如下的数组做平方运算:
int
[] nums = [
1
,
2
,
3
,
6
,
8
]
as
int
[]
对于
Java
语言的解决方案是增加一个计算平方的方法,如下:
def
static
sqr(
int
x)
{
cal(x,
2
)
}
则上述的数组可以做如下的运算:
nums.
each
{
println
sqr(it)
}
这段代码再往下,我们要对下面的数组做立方运算:
int
[] num1s = [
1
,
5
,
4
,
6
,
7
]
as
int
[]
则我们又要增加一个计算立方的方法:
def
static
cube(
int
x)
{
cal(x,
3
)
}
可以看到,由于需求的增加,我们要不断的增加方法来满足新的需求。这种情况,不论是对于公用代码的提供者,还是公用代码的使用者,都是相当麻烦的。
如果使用闭包来解决这个问题,则公用代码的提供者只需要提供一个方法,即:
def
static
cal = {
int
x,
int
y ->
y**x
}
而客户端在使用这个闭包,就成了下面的样子:
def
sqr = cal.curry(
2
)
int
[] nums = [
1
,
2
,
3
,
6
,
8
]
as
int
[]
nums.
each
{
println
sqr(it)
}
println
'--------------------------'
def
cube = cal.curry(
3
)
int
[] num1s = [
1
,
5
,
4
,
6
,
7
]
as
int
[]
num1s.
each
{
println
cube(it)
}
可以看到,这种对闭包进行
curry
运算的解决方案,的确是要比上面的解决方案简单一些,而且更加方便和灵活得多。
上面的代码的运行结果为:
1
4
9
36
64
--------------------------
1
125
64
216
343
经过了上面的介绍,你可能会说,闭包的curry方法非常方便,我喜欢使用它。但是,我也有问题,就是遗留的Java语言工具类,我可以使用闭包的curry方法吗?
当然可以,我们还是来看看实际的例子吧。
下面是我们的Java类:
public
class
Tools {
public
static
int
cal(
int
x,
int
y)
{
return
(
int
)Math.pow(x, y);
}
}
现在我们在Groovy语言中使用它:
def
cal = Tools.&cal;
def
sqr = cal.curry(
2
)
int
[] nums = [
1
,
2
,
3
,
6
,
8
]
as
int
[]
nums.
each
{
println
sqr(it)
}
println
'--------------------------'
def
cube = cal.curry(
3
)
int
[] num1s = [
1
,
5
,
4
,
6
,
7
]
as
int
[]
num1s.
each
{
println
cube(it)
}
使的,在
Groovy
语言中,“
.&
”运算符就可以将一个方法转变为一个闭包,如上面的:
def
cal = Tools.&cal;
然后,我们就可以对
cal
对象进行闭包的任何操作。