[阿强的自学之路]----Scala学习笔记 Day07:函数的闭包、柯里化、递归、控制抽象和懒加载

闭包

什么是闭包?

如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的 环境,称为闭包。

闭包的应用:

在大数据环境下,需要对一系列数据进行类似的操作,如:将标号为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修饰的变量时,它只有在值被调用时才会运行。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值