在以下代码中:
def product(f: Int => Int)(a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1, b)
将参数a
和b
传递给内部函数,但您可以编写完全相同的函数定义,如下所示:
def product(f: Int => Int, a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f, a + 1, b)
那么分离参数的目的是什么?换句话说,为什么这样做:
(f: Int => Int)(a:Int, b:Int)
当你可以更清楚地写道:
(f: Int => Int, a:Int, b:Int)
答案 0 :(得分:3)
多个参数列表的另一个特性是部分应用:
def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c
val g: Int => Int => Int = sum3(10) _
val h: Int => Int = g(20)
val r: Int = h(30) // 10 + 20 + 30 = 60
您可以部分应用一个函数并获得另一个与原始函数等效但其中一个参数已修复的函数。需要_
后才sum3(10)
因为sum3
是方法,而不是函数,_
将方法转换为函数。
当您使用高阶函数时,这非常有用:
def adder(x: Int)(y: Int) = x + y
Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14)
当部分应用的方法/函数用作高阶调用的参数时,不需要_
,语法变得非常简洁。
答案 1 :(得分:1)
此功能的另一个用例是,如果您想创建一个看起来像Scala编程语言本身内置的控制结构。
例如,我可以编写一个名为times
的控制结构,它通过以下方法定义帮助我完全n
次执行代码块:
// since block is call by name, it will not be evaluate when you call it.
def times(n: Int)(block: => Any): Unit = {
for (i <- 0 until n) {
block // evaluate(execute) block
}
}
// Now I can use the times method like a control structure
times(5) {
println("Hello World");
}
答案 2 :(得分:0)
取决于是否存在隐含参数(无法与普通参数正确混合)...
def foo(i: Int)(implicit p: P): Foo
......以及你想要的方式......
def foo1(a: Int)(b: Int => Boolean): Boolean
foo1(9) { i => false }
def foo2(a: Int, b: Int => Boolean): Boolean
foo2(9, { i => false })