Scala既是一门面向对象(OOP)语言,又是一门函数式编程(FP)语言。作为一门支持函数式编程的语言,Scala鼓励面向表达式编程(EOP)模型。简单来说,EOP中每个语句都有返回值。这一模式很明显,因为if/else语句就可以返回值:
val result = if(a > b) a else b
1. 使用函数字面量(匿名函数)
val a = List.range(1,10)
val b = a.filter((i:Int) => i % 2 == 0)
println(b)
结果:
List(2, 4, 6, 8)
Process finished with exit code 0
在上面的例子中代码:
(i:Int) => i % 2 == 0
就是匿名函数。
2. 将函数转变为变量
val double = (i:Int) => {i * 2}
println(double(3))
结果:
6
这个时候的变量double是一个实例。在这种情况下他是函数实例你可以像函数一样去调用他。
除了调用,还可以将其传入到任何具有相同参数签名的方法或者函数中:
val double = (i:Int) => {i * 2}
val list = List.range(1,5)
val l =list.map(double)
println(l)
结果:
List(2, 4, 6, 8)
Process finished with exit code 0
Scala的Unit类:
Unit类和java的Void类似,使用于表明函数无返回值的场景。比如我们定义main函数:
def main(args: Array[String]): Unit = {
}
3. 使用闭包
先看一个例子:
package scope{
class Foo{
def exec(f:String => Unit,name:String): Unit ={
f(name)
}
}
}
object claEx extends App{
var hello = "hello"
def sayHello(name:String){println(s"$hello,$name")}
val foo = new scope.Foo
foo.exec(sayHello,"hah")
}
结果:
hello,hah
Process finished with exit code 0
关于闭包的定义有很多,有如下的说法,”闭包是满足下面三个条件的一段代码块”:
- 代码块可以当作值来传递。
- 同时可以被任何拥有该值的对象按需执行。
- 可以引用上下文中已经创建的变量(如它的封闭是相对于变量访问,在数学上称之为“关闭”)。
再举一个简单的例子:
object Demo{
def main(args: Array[String]): Unit = {
val newAge = 18
val isMoreThanAge = (age:Int) => age >= newAge
println(isMoreThanAge(3))
println(isMoreThanAge(40))
printResult(isMoreThanAge,33)
}
def printResult(f:Int => Boolean,x:Int): Unit ={
println(f(x))
}
}
结果:
false
true
true
Process finished with exit code 0
4.部分应用函数
先看定义:
val sum = (a:Int,b:Int,c:Int) => a+b+c
val f = sum(3,6,_:Int)
在函数调用的时候不提供第三个参数,这个时候函数f就变为部分应用函数。
val sum = (a:Int,b:Int,c:Int) => a+b+c
val f = sum(3,6,_:Int)
println(f.toString())
结果:
Demo$$$Lambda$2/1329552164@1b40d5f0
结果表明f是一个Function。因为上面第三个参数为Int类型的空缺值,所以f函数还可以传入一个参数:
println(f(3))
结果:
12