二.scala函数
在最前面有介绍到,函数就是对象。那为什么函数能直接运行呢?这其实得益于object的apply这个语法糖。
偏函数
偏函数(PartialFunction),从某种意义上来说,偏函数也是scala中挺重要的一个语法糖。
偏函数它长这样:
PartialFunction[A, B] //接收一个A类型的参数,返回B类型的参数
值得一提的是,scala中有一个关键字case,就是使用偏函数。继续举例子:
//下面的case就是一个偏函数PartialFunction[Int, String]
scala> val one: PartialFunction[Int, String] = { case 1 => "one" }
one: PartialFunction[Int,String] = <function1>
scala> one(1)
res11: String = Int
scala> one("one")
<console>:13: error: type mismatch;
found : String("one")
required: Int
one("one")
case关键字会匹配符合条件的类型或值,如果不符合,会报错。内部实现就不介绍了,知道是个常用语法糖就好。
而这个case关键字也正是实现scala模式匹配中,必不可少的一环,有兴趣的童鞋可以看看我这篇:scala模式匹配详细解析
这里再说一个常见应用吧,函数组合子中有一个collect,它需要的参数就是一个偏函数。下面看个有意思的例子:
//这个list里面的Any类型
scala> val list:List[Any] = List(1, 3, 5, "seven")
list: List[Any] = List(1, 3, 5, seven)
//使用map会报错,因为map接收的参数是普通函
scala> list.map { case i: Int => i + 1 }
scala.MatchError: seven (of class java.lang.String)
at $anonfun$1.apply(<console>:13)
at $anonfun$1.apply(<console>:13)
at scala.collection.immutable.List.map(List.scala:277)
... 32 elided
//但如果用collect函数就可以,因为collect接收的参数是偏函数,它会自动使用偏函数的一些特性,所以可以自动过滤掉不符合的数据类型
scala> list.collect { case i: Int => i + 1 }
res15: List[Int] = List(2, 4, 6)
因为collect接收的参数是偏函数,它会自动使用偏函数的特性,自动过滤不符合的数据类型,而map就做不到。
部分应用函数
所谓部分应用的意思,就是说,当调用一个函数时,可以仅传递一部分参数。而这样会生成一个新的函数,来个实例看看吧:
//定义一个打印两个输出参数的函数
scala> def partial(i:Int,j:Int) : Unit = {
| println(i)
| println(j)
| }
partial: (i: Int,j: Int)Unit
//赋一个值给上面那个函数,另一个参数不赋值,生成一个新的函数
scala> val partialFun = partial(5,_:Int)
partialFun: Int => Unit = <function1>
//只要一个参数就可以调用啦
scala> partialFun(10)
5
10
部分应用函数,主要是作用是代码复用,同时也能够增加一定的代码可读性。
当然还有更多有意思的用法,后面有机会说到再说。









