scala学习笔记(十):本地函数、偏函数、部分应用函数

     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 = <function1>
  * Function类型有多个版本,Function0表示无参数函数,Function1表示只有一个参数的函数
  * PartialFunction还是Function1d的子类
 */
def p_sum = sum(1, _:Int)
println(p_sum(4))

输出:
5

猜你喜欢

转载自gbjian001.iteye.com/blog/2347608