一个方法可以定义多参数列表。当调用一个不全的参数列表的方法时,会产生一个函数并将缺少的参数列表作为参数。这有个正式定义叫柯里化。
下面的例子定义在Scala集合中的Traversable特质当中:
1 | def foldLeft[B](z: B)(op: (B, A) => B): B |
foldLeft
按照从左往右的顺序,将二进制运算符op
作用于初始值z
和这个traversable
中的所有元素。下面展示了它的用法。
从一个初始值0开始,foldleft
将函数(m, n) => m + n
作用于列表中的每个元素和上一次的累计值。
1 | val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |
多参数列表具有比较冗长的调用语法,因此要谨慎使用。建议使用的场景包括以下:
单个函数参数
在单个函数参数的场景(如上面foldleft
中的op
)中,多参数列表允许使用简洁的语法将匿名函数传递给方法。如果没有多参数列表,代码将会是这样:
1 | numbers.foldLeft(0, {(m: Int, n: Int) => m + n}) |
注意这里多参数列表的用法还可以让我们利用Scala类型推断来让代码变得更加简洁,这在不用柯里化来定义的情况下是做不到的。
1 | numbers.foldLeft(0)(_ + _) |
上面的语句numbers.foldLeft(0)(_ + _)
允许我们固定参数z
,然后传递一个偏函数进行使用,正如:
1 | val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |
最后说下,foldLeft
和foldRight
可以使用下面任意一种用法来调用。
1 | val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |
隐式参数
如果要将参数列表中的某些参数指定为implicit
,则应该使用多参数列表。如下所示:
1 | def execute(arg: Int)(implicit ec: ExecutionContext) = ??? |