前言
在Spark中会经常看见一种在Java中没有的语法(此处Java特指Java8+),类似下面这样子的:
pairs.filter{case (key, value) => value.length < 20}
在scala中函数是不支持元组作为参数的,因此就需要引入偏函数这个概念。
什么是偏函数
偏函数是一种可以对参数类型进行判断,从而选择合适的处理方式的语法。
偏函数的基本形式如下所示:
val pf2:PartialFunction[Any,String]={case d:Double=>"double"}
这里声明了一个偏函数变量,偏函数接收一个Double类型的参数,然后返回一个字符串"double"。
偏函数有什么用
使用偏函数,我们可以根据参数类型的不同选择不同的处理方式。
比如,下面这样
val mypf:PartialFunction[Any,String]={case d:Double=>"double";case s:String=>"String"}
printf("%5s %5s\n",mypf(1.5),mypf("abc"))
类比Java的Case用法,可知输出结果为"double String"。相比于多态来说,通过偏函数来实现,函数更加简洁。同时,偏函数不仅支持普通类型的参数,还支持元组类型的参数,相比于普通的函数来说适用范围更加广泛。
什么时候用偏函数
理论上来说,所有涉及到多态的情况都可以使用偏函数来简化代码。
另外,由于偏函数支持使用元组,因此偏函数可以应用于需要以元组作为函数参数的情况。例如在spark中PairRDD是通过元组的形式进行存储的。因此我们在遍历PairRDD的时候就必然需要用到偏函数来实现相关逻辑。
关于偏函数需要注意的事项
其实偏函数就是一种scala的简化语法,没有太多需要注意的地方。唯一需要注意的是,偏函数的参数类型不是必须的,如果我们不声明参数类型的话,那么就会接受所有的参数类型。
val mypf:PartialFunction[Any,String]={case a=>"any";case s:String=>"String";}
printf("%5s\n",mypf("abc"))
对于上面的例子,很明显对于case a这种情况,就是默认接收所有的参数。如果这个时候传入一个字符串,那么就会返回一个"any"字符串。后面的情况尽管也是符合的,但是由于函数已经返回了,所以后面的Case将不会执行。也就是意味着后面的代码将是没有用的。
关于这一点,在开发的时候需要特别注意。