闭包
什么是闭包?
如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包。
闭包的应用:
在大数据环境下,需要对一系列数据进行类似的操作,如:将标号为0-200的数据+4,201-400的数据+5,401-600的数据+6 =====
这种情况下,可以像下面这个例子这样操作:
def addByA(a:Int):Int => Int = {
def addByB(b:Int): Int={
a+b
}
}
这样在调用的时候,可以这样:
val addByFour = addByA(4)
在调用addByFour时,就可以实现对每一个数据加4的操作。
小例子:
def main(args: Array[String]): Unit = {
val arr:Array[Int] = Array(1,2,3,4,5,6,7,8)
def addByA(a:Int):Int=>Int = {
def addByB(b:Int):Int =a+b
addByB
}
val addByFour = addByA(4)
def func(arr:Array[Int],op:Int=>Int): Array[Int] ={
for(elem <- arr) yield op(elem)
}
val narr :Array[Int] = func(arr,addByFour)
println(narr.mkString(","))
}
输出结果为:
5,6,7,8,9,10,11,12
addByA函数可以用lambda表达式简化:
def addByA(a:Int):Int=>Int = b => a+b
函数柯里化:
把一个参数列表的多个参数,变成多个参数列表。
def main(args: Array[String]): Unit = {
def add(a:Int)(b:Int):Int = {
a+b
}
val addA = add(4)(5)
}
递归:
一个函数又调用自身,称之为递归。
小例子:递归实现阶乘:
def recursion(i:Int):Int={
if(i>1) recursion(i-1)*i else 1
}
尾递归:节约栈的空间,防止栈溢出
def tailFact(n:Int):Int = {
def loop(n:Int,current:Int):Int = {
if (n>1) loop(n-1,current * n) else current
}
loop(n,1)
}
控制抽象
def main(args: Array[String]): Unit = {
//值调用:把计算后的值传过去
def add(a:Int,b:Int):Int= a+b
println(add(3,5))
//名调用:把代码传递过去
def m1(a: => Int):Unit = {
println(s"a=${a}")
}
def m2():Int = {
println("我是m2")
12
}
m1(m2())
}
控制抽象小例子:自定义while循环
def main(args: Array[String]): Unit = {
def myWhile(condition: => Boolean): (=>Unit) => Unit ={
def loop(op: => Unit) : Unit = {
if (condition) {
op
myWhile(condition)(op)
}
}
loop _
}
var n = 10;
myWhile(n >= 1){
println(n)
n -= 1
}
}
while循环的结构如下:
while(判断条件){
循环代码
}
想起闭包中,可以用()()的形式来调用传递参数,我们自定义一个mywhile函数,内部还有一个loop函数,两个函数的参数都是一段代码:
mywhile({ 代码段1 })({ 代码段2 })
当代码段1位TRUE时,执行代码段2的代码,并且使用时可以简化,最终的效果和while一模一样。
懒加载
当一个函数被赋值给lazy修饰的变量时,它只有在值被调用时才会运行。