方法可以有多个形参列表
例子
这里有个例子,在Scala集合Api中,特性Iterable 定义如下:
trait Iterable[A] { ... def foldLeft[B](z: B)(op: (B, A) => B): B ... }
foldLeft 将两个参数的函数 op 应用于一个初始值z 上。然后所有集合的元素 ,从左到右。下面的列子是它的用法
起始值为0,foldLeft 这里应用了函数 (m,n)=> m+n 来使列表中的每个元素与前一个值进行累加。
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55
使用案例
建议多个参数列表的使用案例包括:
驱动器类型判断
碰巧在Scala中,类型推断一次处理一个参数列表。你有如下的方法:
def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ???
然后你可以用如下的方式调用它,然后发现它不能通过编译
def notPossible = foldLeft1(numbers, 0, _ + _)
你必须用下面的其中的一种方法进行调用:
def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _)
def secondWay = foldLeft1(numbers, 0, (a: Int, b: Int) => a + b)
这是因为Scala不能同时推断函数 _+_ 和 A、B。 通过将参数 op 移动至它自身的参数列表 ,第一个参数列表中的A和B的类型才能推断出来。这个被推断出来的类型就可以被应用与 _+_ 的类型推断,最终推断的结果为 (Int,Int) => Int
def foldLeft2[A, B](as: List[A], b0: B)(op: (B, A) => B) = ???
def possible = foldLeft2(numbers, 0)(_ + _)
这种定义方式就不需要额外的声明,所有参数的类型都能推断出来。
隐式参数
要将某些参数仅指定为隐式,必须将它们放到隐式参数列表中
举例如下
def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ???
局部应用
当一个方法被调用时缺少了一些数字或者参数列表,这时候便会产生一个以缺失形参列表作为实参的函数。这个被人称为局部应用的
举例:
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]()) _ val squares = numberFunc((xs, x) => xs :+ x*x) println(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) val cubes = numberFunc((xs, x) => xs :+ x*x*x) println(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)
【注: 大概意思就是函数名也可以做变量。触发函数时在这个变量后面加个括号】