Scala函数和闭包
函数和闭包
方法
定义函数最通用的方法是作为某个对象的成员,这种函数被成为方法
def processFile(fileName: String,width: Int){
...
}
本地函数
Java里达成这个目的的主要工具是私有方法(pirvate),这种在scala里同样有效,但是Scala提供了另一种方式:你可以把函数定义在别的函数之内,就好像本地变量那样,这种本地函数仅在包含它的代码块中可见
def processFile(fileName: String,width: Int){
def processLine(fileName: String,width: Int,line: String){
...
}
val source=Source.fromFile(fileName)
for(line <- source.getLines){
processLine(fileName,width,line)
}
}
头等函数
Scala的函数是头等函数,你不仅可以定义和调用函数,还可以把它们写成匿名的字面量,并把他们作为值传递
/*对数执行递增操作的函数字面量例子
* =>指明这个函数把左边的东西(任何整数x)转变成右边的东西(x+1)
*/
(x: Int) => x+1
函数值是对象,可以将其存入变量,它们也是函数,所以可以使用通常的括号函数调用写法调用它们
var increase=(x: Int) => x+1
increase: (Int) => Int = <function>
//调用
increase(10)
res0: Int=11
如果想让函数体字面量包含多条语句,可以用花括号包住函数体,一行放一条语句,这样就组成了代码块
increase =(x: Int) => {
println("We")
println("are")
println("here")
x+9
}
函数字面量的短格式
Scala提供了许多方法去除冗余信息并把函数字面量写得更简短,注意留意这些机会,因为它们能让你去掉代码里乱七八糟的东西,一种让函数字面量更简短的方式是去除参数类型,另一种去除无用字符的方式
//简化之前
val someNumbers=List(-2,-3,-6,6,8,9)
someNumbers.filter((x: Int) => x >0)
res0: List[Int]=List(6,8,9)
//简化之后
someNumbers.file(x => x>0)
res0: List[Int]=List(6,8,9)
占位符语法
如果想让函数字面量更简洁,可以把下划线当做一个或更多参数的占位符,只要每个参数在函数字面量内仅出现一次,你可以把下划线看作表达式里需要被“填入”的“空白”,这个空白在每次函数调用的时候用函数的参数填充
someNumbers.filter(_ >0)
res0: List[Int]=List(6,8,9)
//_+_将扩展成带两个参数的函数字面量
val f=(_: Int) + (_: Int)
f: (Int,Int) => Int = <function>
f(5,10)
res0: Int=15
闭包
依照函数体字面量在运行时创建的函数值(对象)被称为闭包:closure,名称源自于通过“捕获”自由变量的绑定,从而对函数字面量执行的“关闭”行动。
val someNumbers=List(-11,-10,-5,0,5,10)
var sum=0
someNumbers.foreach(sum += +)
sum
Int = -11
重复参数
Scala中,你可以指明函数的最后一个参数是重复的,从而允许客户向函数传入可变长度参数列表,想要标注一个重复参数,可再参数的类型之后放一个星号,函数内部重复参数的类型声明的数组,例如:echo函数里被声明为类型“String*”的args的类型实际上是Array[String]
def echo(args: String*)=
for(arg <- args)
println(arg)
echo()
echo("Hello")
echo("Hello","world")
val arr=Array("what","up","door")
//_*标注告诉编译器把arr的每个元素当做参数,而不是当做单一的参数传给echo
echo(arr: _*)
----EOF-----