简介

  1. 闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包
  2. 函数柯里化:把一个参数列表的多个参数,变成多个参数列表 ```scala def func(i: Int): String=>(Char=>Boolean) = { def f1(s: String): Char=>Boolean = {

    1. def f2(c: Char): Boolean = {
    2. if (i == 0 && s == "" && c == '0') false else true
    3. }
    4. f2

    } f1 }

    println(func(0)(“”)(‘0’)) println(func(0)(“”)(‘1’)) println(func(23)(“”)(‘0’)) println(func(0)(“hello”)(‘0’))

  1. 随着func, f1, f2 的不断出栈, 里面依赖的外面变量也会销毁. 那么里面要用到外面的变量怎么办?<br />scala里面其实, 函数也是对象.<br />当里面要用到外面的变量的时候, 就是把上一个的对象在堆里面存着的, 里面就能用到了
  2. <a name="VvRgN"></a>
  3. # 闭包
  4. 闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包
  5. ```scala
  6. // 将固定加数作为另一个参数传入,但是是作为”第一层参数“传入
  7. def addByFour1(): Int=>Int = {
  8. val a = 4
  9. def addB(b: Int): Int = {
  10. a + b
  11. }
  12. addB
  13. }
  14. def addByA(a: Int): Int=>Int = {
  15. def addB(b: Int): Int = {
  16. a + b
  17. }
  18. addB
  19. }
  20. println(addByA(35)(24))
  21. val addByFour2 = addByA(4)
  22. val addByFive2 = addByA(5)
  23. println(addByFour2(13))
  24. println(addByFive2(25))

lambda表达式简写, 不断省略

  1. def addByA1(a: Int): Int=>Int = {
  2. (b: Int) => {
  3. a + b
  4. }
  5. }
  6. def addByA2(a: Int): Int=>Int = {
  7. b => a + b
  8. }
  9. def addByA3(a: Int): Int=>Int = a + _
  10. val addByFour3 = addByA3(4)
  11. val addByFive3 = addByA3(5)
  12. println(addByFour3(13))
  13. println(addByFive3(25))

柯里化

函数柯里化:把一个参数列表的多个参数,变成多个参数列表

  1. def addCurrying(a: Int)(b: Int): Int = {
  2. a + b
  3. }
  4. println(addCurrying(35)(24))

不同写法

现在我们来定义一个接收两个整数,返回两者之和的柯里化函数:
第一种

  1. scala> def sum(a:Int)(b:Int) = a+b
  2. sum: (a: Int)(b: Int)Int

第二种:

  1. scala> def sum(a:Int) = (b:Int) => a+b
  2. sum: (a: Int)Int => Int

第三种:

  1. scala> def sum = (a:Int) => (b:Int) => a+b
  2. sum: Int => (Int => Int)

第四种:这一种和第三种本质上是一样的,使用了scala自定义的一个工具方法。

  1. scala> def sum =((a:Int,b:Int) => a+b).curried
  2. sum: Int => (Int => Int)

使用的时候需要注意的是:
1、前三种方法可以出现在同一个命名空间,也就是可以同时定义成同一个方法名,编译的时候不会报错。但是使用的时候会出错。(第三、四种方法本质是一样的,所以不能同时定义)
2、使用柯里化的目的是使用它可以分步计算的特性,但是这三种定义方法获得第一步计算返回的匿名方法的方式不一样。