Scala学习笔记(6)——函数柯里化&闭包

一、函数的闭包

1.闭包的概念

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

在下面这个函数中,func和f1执行完毕后都从JVM的stack中弹出了,为什么执行f2时还能访问到func和f1中的变量值呢?与Java不同的是,在Scala中函数也是一个对象,当我们调用了一个函数时,相当于在JVM的heap中创建了一个对应的对象实例,所依赖的外部环境和局部变量都保存在这个实例里,这就是所谓的闭包保存的实体

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
    }

2.闭包的应用

我们可以利用函数闭包以及可以将函数作为返回值的特性,来,比如有一批数据需要进行加4操作,另一批数据需要进行加5操作,核心操作一样但是固定参数不一样,这时我们就可以通过在一个外层函数中传入不同的参数(比如4或5)返回得到对应需求的函数

	def addByA(a: Int): Int=>Int = {
      def addB(b: Int): Int = {
        a + b
      }
      addB
    }
    //根据传入的参数得到不同的函数
	val addByFour2 = addByA(4)
    val addByFive2 = addByA(5)
	//利用得到的函数再去进行数据操作
    println(addByFour2(13))
    println(addByFive2(25))

二、函数的柯里化

1.柯里化的概念

函数柯里化:把接受多个参数的函数变换成接受一个参数(最初函数的第一个参数)的函数,并将函数的返回值修改为接收剩余参数执行原函数体的函数,如果剩余参数有多个,这个接受剩余参数的函数还可以继续进行柯里化。

对于柯里化后的函数,当我们一次传入所有参数时,其功能特性就和柯里化前一样返回一样的值,但是当我们只传入前几个参数时,我们就可以得到一个接收剩余参数的函数,这就提供了很大的灵活性。

2.柯里化的应用

比如上述例子中的addByA函数,我们就可以用柯里化来替代实现

	def add(a: Int, b: Int): Int = {
      a + b
    }
	//对add()进行柯里化
    def addCurrying(a: Int)=(b: Int): Int = {
      a + b
    }
    //可简写为
    def addCurrying1(a: Int)(b: Int) = a + b
	//只传入第一个参数,就得到一个以b为参数的函数(函数体中a固定为4)
    val addByFour2 = addCurrying(4)

同样对于三个整数乘法的函数在scala中由于有柯里化的存在,自然有多种功能等价的函数定义形式,如以下四种函数都是实现了三个整数乘法功能,只不过调用不同形式参数过程略有不同,直接参入三个参数的一步到位就可以得到运算结果,而传入1或者2个参数的需要分步骤再传入第2/3或者第3个参数才能求出三个整数相乘的结果,很好地体现了延迟执行或者固定易变因素等方面能力
def multiplie3par(x:Int,y:Int,z:Int)=xyz
def multiplie3par1(x:Int)=(y:Int,z:Int)=>xyz
def multiplie3par2(x:Int)(y:Int)(z:Int)=xyz
def multiplie3par3(x:Int)(y:Int)=(z:Int)=>xyz
编译执行的结果都是一样

参考文章:Scala中的柯里化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值