专栏原创出处:github-源笔记文件 (opens new window) ,github-源码 (opens new window),欢迎 Star,转载请附上原文出处链接和本声明。
Scala 编程语言专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Scala 编程语言 (opens new window)
# 什么是柯里化
柯里化就是未使用全部的参数列表调用多参数列表的方法时,会得到一个函数,该函数接收前面未使用的参数列表作为其参数。
- 方法可以定义多个参数列表,一个
()
包含的内容即为一个参数列表。
# foldLeft 示例
在 Scala 集合 trait TraversableOnce 定义了 foldLeft。
foldLeft 对一个集合进行运算,将函数 op 应用到初始值 z 和集合从左往右的第一个元素上
然后将函数 op 应用到计算结果和集合的下一个元素上,依次类推,直到计算完集合中的所有元素。
// scala LinearSeqOptimized 中定义的 foldLeft 方法 def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = { var acc = z var these = this while (!these.isEmpty) { acc = op(acc, these.head) these = these.tail } acc } val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 由于 foldLeft 是柯里化方法,有两个参数列表,当只使用第一个参数列表调用该方法时 // 会得到一个函数,该函数以剩余的参数列表作为参数,即 (B, A) => B // 由于第一个参数列表传入 0,scala 自动推断类型,得到剩余一个参数的类型 (Int, Int) => Int // 最终返回一个高阶函数,返回的高阶函数的类型为:((Int, Int) => Int) => Int val fold: ((Int, Int) => Int) => Int = numbers.foldLeft(0) val res = fold((x, y) => x + y) print(res) // 55 // 也可以使用所有的参数列表进行柯里化方法的调用 numbers.foldLeft(0)((x, y) => x + y) // 上述调用可以实现方法的复用,可以在 fold 的基础上定义其他计算过程 val res2 = fold((x, y) => x * y) // 如果不使用多参数列表,而是采用匿名函数作为参数调用方法,写法更为繁琐 // scala 无法进行类型推断,需要手动指明函数参数的类型 numbers.foldLeft(0, {(m: Int, n: Int) => m + n}) // 使用 scala 的类型推断可以让柯里化方法的调用更为简洁 // 第一个 _ 代表初始值或者该函数运算的结果,第二个 _ 代表集合中的下一个元素 numbers.foldLeft(0)(_ + _)
Copied!
# 有关 foldLeft 和 foldRight 的所有调用形式
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) numbers.foldLeft(0)((sum, item) => sum + item) numbers.foldRight(0)((sum, item) => sum + item) numbers.foldLeft(0)(_+_) numbers.foldRight(0)(_+_) (0 /: numbers)(_+_) // foldLeft (numbers :\ 0)(_+_) // foldRight
Copied!
# 隐式参数
如果要指定参数列表中的某些参数为隐式 (implicit),应该使用多参数列表。
该隐式参数列表必须为最后一个参数列表。
如果要定义多个隐式参数,这些隐式参数必须在同一个参数列表中,参数列表的开头加一个 implicit 关键字即可。
隐式参数不可以和普通参数定义在同一个参数列表中。
更多介绍请参考 《隐式参数》章节。
def execute(arg: Int)(implicit ec: ExecutionContext) = ??? def execute1(arg: Int)(implicit ec: ExecutionContext, tc: String) = ??? def execute2(arg: Int,implicit ec: ExecutionContext) = ??? // does not compile
Copied!