Scala中的函数是Java中完全没有的概念。因为Java是完全面向对象的编程语言,没有任何面向过程编程语言的特性,因此Java中的一等公民是类和对象,而且只有方法的概念。
而Scala是一门既面向对象,又面向过程的语言。因此在Scala中有非常好的面向对象的特性,可以使用Scala来基于面向对象的思想开发大型复杂的系统和工程;而且Scala也面向过程,因此Scala中有函数的概念。在Scala中,函数与类、对象等一样,都是一等公民。Scala中的函数可以独立存在,不需要依赖任何类和对象。
1、本地函数,其实本地函数就是定义在函数内部的函数
def processData(fileName:String,width:Int){ //定义本地函数-("内部/私有函数...") def processLine(line:String){ if(line.length>width) println(fileName+":"+line) } val source=Source.fromFile(fileName) for(line<- source.getLines()) processLine(line)//调用本地函数 }
2、偏函数 PartialFunction 偏函数是个数学概念, 偏函数不是"函数"的一种, 而是一个跟函数平行的概念,它是指定义域X中可能存在某些值在值域Y中没有对应的值,
/** PartialFunction特质规定了两个要实现的方法:apply和isDefinedAt * PartialFunction[]中第一个泛型表示传递进行参数的类型,第一个泛型表示返回值的类型 * 因为case语句只能声明一个变量,那么偏函数受限于此,也只能有一个参数 */ val par = new PartialFunction[Any,Int] { //isDefinedAt用来告知调用方这个偏函数接受参数的范围 override def isDefinedAt(x: Any): Boolean = if(x.isInstanceOf[Int]) true else false //apply方法用来描述对已接受的值如何处理 override def apply(v1: Any): Int = v1.asInstanceOf[Int] + 1 } List(1,3,8,"two") collect par foreach(println)
但是这样使用起来真得非常笨拙,其实还有一种方式来定义偏函数,那就是模式匹配
val spar:PartialFunction[Any,Int] = {case i:Int => i + 1} List(1,3,8,"two") collect spar foreach(println) 输出: 2 4 9
但是我需要分别匹配2个怎么办?orElse
val num:PartialFunction[Any,Int] = {case x:Int => x * 3} val str:PartialFunction[Any,String] = {case x => x + " is String"} println("PartialFunction orElse") List(1,2,3,"one") collect (num orElse str) foreach println 输出: 3 6 9 one is String
case 有时候是可以被编译成匿名函数,但是如果List里面包含的元素和case里面不匹配的话就会出错
/** * 一个case语句就是一个独立的匿名函数 * case i:Int => i +3 等价 (i:Int) =>i +3 */ List(1,2,3) map {case i:Int => i +3} foreach(println) //collect 接受的是PartialFunction偏函数 List(1,2,3) collect {case i:Int => i +3} foreach(println) //map接受的是一个函数 所以到了one元素的时候会报类型错误 //List(1,2,3,"one") map {case i:Int => i +3} foreach(println) val num:PartialFunction[Any,Int] = {case x:Int => x * 3} val str:PartialFunction[Any,String] = {case x => x + " is String"} println("PartialFunction orElse") //只要保证list元素能在偏函数中匹配完就不会报错 List(1,2,3,"one") map (num orElse str) foreach println
3、部分应用函数 Partial Applied Function 是指一个函数有N个参数, 而我们为其提供少于N个参数, 那就得到了一个部分应用函数
def sum(a:Int,b:Int) = a + b ; /** * p_sum: Int => Int =* Function类型有多个版本,Function0表示无参数函数,Function1表示只有一个参数的函数 * PartialFunction还是Function1d的子类 */ def p_sum = sum(1, _:Int) println(p_sum(4)) 输出: 5