欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Scala 基础教程10 -- 多个参数列表 (CURRYING)

程序员文章站 2022-06-14 18:56:47
...

10 多个参数列表(CURRYING)

方法可以定义多个参数列表。当使用较少数量的参数列表调用方法时,这将产生一个函数,将缺少的参数列表作为其参数。这正式称为currying。
这是一个示例,在Scala集合的Traversable trait中定义:

def foldLeft[B](z: B)(op: (B, A) => B): B

foldLeft将二元运算符op应用于初始值z以及此可遍历的所有元素,从左到右。下面显示的是它的用法示例。
从初始值0开始,foldLeft此处将函数应用于(m, n) => m + nList中的每个元素和先前的累计值。

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m, n) => m + n)
print(res) // 55

多个参数列表具有更详细的调用语法; 因此应该谨慎使用。建议的用例包括:

10.1 单一功能参数

在单个功能参数op的情况下,foldLeft如上所述,多个参数列表允许简明的语法将匿名函数传递给该方法。如果没有多个参数列表,代码将如下所示:

numbers.foldLeft(0, {(m: Int, n: Int) => m + n})

请注意,这里使用多个参数列表还允许我们利用Scala类型推断使代码更简洁,如下所示; 这在非咖喱定义中是不可能的。

numbers.foldLeft(0)(_ + _)

上面的语句numbers.foldLeft(0)(_ + _)允许我们修复参数z并传递部分函数并重用它,如下所示:

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)
print(squares.toString()) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

val cubes = numberFunc((xs, x) => xs:+ x*x*x)
print(cubes.toString())  // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)

最后,foldLeft并且foldRight可以在任何下列用语的使用,

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
numbers.foldLeft(0)((sum, item) => sum + item) // Generic Form
numbers.foldRight(0)((sum, item) => sum + item) // Generic Form
numbers.foldLeft(0)(_+_) // Curried Form
numbers.foldRight(0)(_+_) // Curried Form
(0 /: numbers)(_+_) // Used in place of foldLeft
(numbers :\ 0)(_+_) // Used in place of foldRight

10.2 隐含参数

要将参数列表中的某些参数指定为implicit,应使用多个参数列表。一个例子是:

def execute(arg: Int)(implicit ec: ExecutionContext) = ???
相关标签: Scala currying