从上面的示例可以看出重新声明 more 后,全局的 more 的值是 100,但是对于闭包函数 addMore10 还是引用的是值为 10 的 more,这是由虚拟机来实现的,虚拟机会保证 more 变量在重新声明后,原来的被捕获的变量副本继续在堆上保持存活。
三、高阶函数 3.1 使用函数作为参数定义函数时候支持传入函数作为参数,此时新定义的函数被称为高阶函数。
object ScalaApp extends App { // 1.定义函数 def square = (x: Int) => { x * x } // 2.定义高阶函数: 第一个参数是类型为 Int => Int 的函数 def multi(fun: Int => Int, x: Int) = { fun(x) * 100 } // 3.传入具名函数 println(multi(square, 5)) // 输出 2500 // 4.传入匿名函数 println(multi(_ * 100, 5)) // 输出 50000 } 3.2 函数柯里化我们上面定义的函数都只支持一个参数列表,而柯里化函数则支持多个参数列表。柯里化指的是将原来接受两个参数的函数变成接受一个参数的函数的过程。新的函数以原有第二个参数作为参数。
object ScalaApp extends App { // 定义柯里化函数 def curriedSum(x: Int)(y: Int) = x + y println(curriedSum(2)(3)) //输出 5 }这里当你调用 curriedSum 时候,实际上是连着做了两次传统的函数调用,实际执行的柯里化过程如下:
第一次调用接收一个名为 x 的 Int 型参数,返回一个用于第二次调用的函数,假设 x 为 2,则返回函数 2+y;
返回的函数接收参数 y,并计算并返回值 2+3 的值。
想要获得柯里化的中间返回的函数其实也比较简单:
object ScalaApp extends App { // 定义柯里化函数 def curriedSum(x: Int)(y: Int) = x + y println(curriedSum(2)(3)) //输出 5 // 获取传入值为 10 返回的中间函数 10 + y val plus: Int => Int = curriedSum(10)_ println(plus(3)) //输出值 13 }柯里化支持多个参数列表,多个参数按照从左到右的顺序依次执行柯里化操作:
object ScalaApp extends App { // 定义柯里化函数 def curriedSum(x: Int)(y: Int)(z: String) = x + y + z println(curriedSum(2)(3)("name")) // 输出 5name } 参考资料Martin Odersky . Scala 编程 (第 3 版)[M] . 电子工业出版社 . 2018-1-1
凯.S.霍斯特曼 . 快学 Scala(第 2 版)[M] . 电子工业出版社 . 2017-7