尽管前面的例子里下划线替代的只是单个参数,你还可以使用一个下划线替换整个参数列表。例如,写成println(_),或者更好的方法你还可以写成println _。下面是一个例子:
someNumbers.foreach(println _)
Scala把这种短格式直接看作是你输入了下列代码:
someNumbers.foreach(x => println(x))
因此,这个例子中的下划线不是单个参数的占位符。它是整个参数列表的占位符。请记住要在函数名和下划线之间留一个空格,因为不这样做编译器会认为你是在说明一个不同的符号,比方说是,似乎不存在的名为println_的方法。
以这种方式使用下划线时,你就正在写一个偏应用函数:partially applied function。Scala里,当你调用函数,传入任何需要的参数,你就是在把函数应用到参数上。如,给定下列函数:
scala> def sum(a: Int, b: Int, c: Int) = a + b + c
sum: (Int,Int,Int)Int
你就可以把函数sum应用到参数1,2和3上,如下:
scala> sum(1, 2, 3)
res12: Int = 6
偏应用函数是一种表达式,你不需要提供函数需要的所有参数。代之以仅提供部分,或不提供所需参数。比如,要创建不提供任何三个所需参数的调用sum的偏应用表达式,只要在“sum”之后放一个下划线即可。然后可以把得到的函数存入变量。举例如下:
scala> val a = sum _
a: (Int, Int, Int) => Int = < function>
有了这个代码,Scala编译器以偏应用函数表达式,sum _,实例化一个带三个缺失整数参数的函数值,并把这个新的函数值的索引赋给变量a。当你把这个新函数值应用于三个参数之上时,它就转回头调用sum,并传入这三个参数:
scala> a(1, 2, 3)
res13: Int = 6
实际发生的事情是这样的:名为a的变量指向一个函数值对象。这个函数值是由Scala编译器依照偏应用函数表达式sum _,自动产生的类的一个实例。编译器产生的类有一个apply方法带三个参数。产生的类扩展了特质Function3,定义了三个参数的apply方法。之所以带三个参数是因为sum _表达式缺少的参数数量为三。Scala编译器把表达式a(1,2,3)翻译成对函数值的apply方法的调用,传入三个参数1,2,3。因此a(1,2,3)是下列代码的短格式:
scala> a.apply(1, 2, 3)
res14: Int = 6