一、匿名函数
在实际工作的时候,比如算法设计可能不需要函数名称,只需要函数执行的功能就可以了,这时候可以使用匿名函数。定义的时候只需要说明输入参数的类型和函数体即可,不需要名称,一般会把这个匿名函数赋值给一个变量(其实是val 常量)。借助函数赋值给变量,变量就变成了函数的性质。
定义匿名函数的语法格式:
((命名参数列表)=>函数实现)(参数列表)
特殊地:
1.无参数:(()=>函数实现)()
2.有一个参数且在最后:(函数实现)(参数)
3.无返回值: ((命名参数列表)=>Unit)(参数列表)
例1. 有参数的匿名函数(参数名称不能省)。
scala> val fun = (x:Int, y:Int) => x+y
fun: (Int, Int) => Int = $$Lambda$1347/1947303038@7f4796e
scala> fun(2,3)
res29: Int = 5
有多条语句的话需要加上大括号
例2. 无参数的匿名函数。
val show = ()=> println("hello world")
scala> show()
hello world
大量的匿名函数增加了代码的阅读难度。看到符号=>就要想到函数,=>左边是输入参数,右边当做函数体,函数体如果只有一条语句,大括号可以省略掉。
二、柯里化
函数的柯里化是指将一个接受n 个参数的函数变成n 个接受一个参数的函数。以接受两个参数的函数为例,第一个函数接受一个参数并返回一个接受一个参数的函数。
原函数:
scala> def add(x:Int, y:Int):Int = {return x+y}
add: (x: Int, y: Int)Int
进行柯里化:
scala> def add(x:Int)= (y:Int)=>x*y(www.daowen.com)
add: (x: Int)Int => Int
这里没有指明返回值类型,交由scala 的类型推断来决定,调用柯里化函数:
scala> add(2)(3)
res32: Int = 6
scala> add(2)
res33: Int => Int = $$Lambda$1350/651092951@4d6cfa5
scala> res33(3)
res34: Int = 6
可以注意到add(2)返回的仍是函数,scala 提供了柯里化函数的简化写法:
scala> def add(x:Int)(y:Int) = x+y
add: (x: Int)(y: Int)Int
如果函数仅有一个参数,那么调用的时候可以使用大括号来代替圆括号。如果使用柯里化,那么所有的函数都可以只有一个参数,这种情况下最后一个参数列表才可以这么做。
scala> add(2){3}
res35: Int = 5
三、闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。闭包可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
如下面这段匿名的函数:
val add = (x:Int) => x + 1
函数体内有一个变量x,它作为函数的一个参数。另如下面的另一段代码:
val add2 = (x:Int) => x + y
在add2 中有两个变量:x 和y。其中的一个x 是函数的形式参数,在add2 函数被调用时,x 被赋予一个新的值。然而y 不是形式参数,而是自由变量,现在对y 赋一初始值:
var y = 3
函数变量add2 成为一个闭包,因为它引用到函数外面定义的变量y,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。当这个自由变量发生变化时,Scala 的闭包能够捕获到这个变化,因此Scala 的闭包捕获的是变量本身而不是当时变量的值。
同样的,如果变量在闭包发生变化,也会反映到函数外面定义的闭包的值。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。