scala里的函数定义还有种被称为currying的方式,
// normal
def foo1(a: String, b: String) = a + " " + b
foo1("hello", "world") // hello world
// currying
def foo2(a: String)(b: String) = a + " " + b
foo2("hello")("world") // hell world
按照programming in scala里的介绍,采用currying方式本质上相当于两个函数调用,
def foo1(a: String)(b: String) = a + " " + b
foo1("hello")("world") // hell world
def foo2(a: String) = (b: String) => a + " " + b
val tmp = foo2("hello")
tmp("world") // hello world
上述两种方式的调用结果是一样的,对于currying定义的函数来说,在进行调用时就是这么一层层进行调用的。采用下面的写法可以获取到隐藏的第二个函数,从函数调用本身来说,这和scala中的partially applied function形式类似,
// currying
def foo(a: String)(b: String) = a + " " + b
val tmp = foo("hello")_
tmp("world") // hello world
// partially appied function
def foo(a: String, b:String) = a + " " + b
val tmp = foo("hello", _:String)
tmp("world") // hello world
currying的目的不是为了再创造一种函数定义方式,它的用途当是允许用户自定义自己的控制结构(语法上看着像)。比如,
// execute op twice
// normal function
def twice(condition: => Boolean, op: => Unit): Unit = {
if (!condition) {
return
}
op
op
}
twice(true, println("foobar")) // foobar, foobar
// currying
def twice(condition: => Boolean)(op: => Unit): Unit = {
if (!condition) {
return
}
op
op
}
twice(true) {
println("foobar")
} // foobar, foobar
上述代码最后的twice就像是scala默认提供的控制结构。currying带来的好处就是这类代码变得可能,估计会对编写dsl带来便利。不过觉得这特性也不好太滥用,大部分情况下普普通通的定义函数就可以了..