简介
- 闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包
函数柯里化:把一个参数列表的多个参数,变成多个参数列表 ```scala def func(i: Int): String=>(Char=>Boolean) = { def f1(s: String): Char=>Boolean = {
def f2(c: Char): Boolean = {
if (i == 0 && s == "" && c == '0') false else true
}
f2
} f1 }
println(func(0)(“”)(‘0’)) println(func(0)(“”)(‘1’)) println(func(23)(“”)(‘0’)) println(func(0)(“hello”)(‘0’))
随着func, f1, f2 的不断出栈, 里面依赖的外面变量也会销毁. 那么里面要用到外面的变量怎么办?<br />scala里面其实, 函数也是对象.<br />当里面要用到外面的变量的时候, 就是把上一个的对象在堆里面存着的, 里面就能用到了
<a name="VvRgN"></a>
# 闭包
闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包
```scala
// 将固定加数作为另一个参数传入,但是是作为”第一层参数“传入
def addByFour1(): Int=>Int = {
val a = 4
def addB(b: Int): Int = {
a + b
}
addB
}
def addByA(a: Int): Int=>Int = {
def addB(b: Int): Int = {
a + b
}
addB
}
println(addByA(35)(24))
val addByFour2 = addByA(4)
val addByFive2 = addByA(5)
println(addByFour2(13))
println(addByFive2(25))
lambda表达式简写, 不断省略
def addByA1(a: Int): Int=>Int = {
(b: Int) => {
a + b
}
}
def addByA2(a: Int): Int=>Int = {
b => a + b
}
def addByA3(a: Int): Int=>Int = a + _
val addByFour3 = addByA3(4)
val addByFive3 = addByA3(5)
println(addByFour3(13))
println(addByFive3(25))
柯里化
函数柯里化:把一个参数列表的多个参数,变成多个参数列表
def addCurrying(a: Int)(b: Int): Int = {
a + b
}
println(addCurrying(35)(24))
不同写法
现在我们来定义一个接收两个整数,返回两者之和的柯里化函数:
第一种
scala> def sum(a:Int)(b:Int) = a+b
sum: (a: Int)(b: Int)Int
第二种:
scala> def sum(a:Int) = (b:Int) => a+b
sum: (a: Int)Int => Int
第三种:
scala> def sum = (a:Int) => (b:Int) => a+b
sum: Int => (Int => Int)
第四种:这一种和第三种本质上是一样的,使用了scala自定义的一个工具方法。
scala> def sum =((a:Int,b:Int) => a+b).curried
sum: Int => (Int => Int)
使用的时候需要注意的是:
1、前三种方法可以出现在同一个命名空间,也就是可以同时定义成同一个方法名,编译的时候不会报错。但是使用的时候会出错。(第三、四种方法本质是一样的,所以不能同时定义)
2、使用柯里化的目的是使用它可以分步计算的特性,但是这三种定义方法获得第一步计算返回的匿名方法的方式不一样。