Scala PartialFunction

PartialFunction是Scala另一个有趣的函数,也非常的有用。
一个PartialFunction[A, B]类型的函数是一个一元函数,接收一个类型为A的参数,返回类型为B的值。但是X的值域可以不覆盖A的整个值域,可以只覆盖部分的值域。其中isDefinedAt可以测试是否一个值是否落在了定义的参数值域上。

如果用简单的白话来讲,就是一个PartialFunction只处理参数的一个子集。

即使对于a:A调用isDefinedAt返回true, 调用apply(a)也可能抛出异常,比如:

1
val f: PartialFunction[Int, Any] = { case _ => 1/0 }

scala.Function1不同的是,PartialFunction可以选择做一些不在参数值域的操作。
比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val sample = 1 to 10
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 0 => x+" is even"
}
// the method collect can use isDefinedAt to select which members to collect
val evenNumbers = sample collect isEven
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 1 => x+" is odd"
}
// the method orElse allows chaining another partial function to handle
// input outside the declared domain
val numbers = sample map (isEven orElse isOdd)

isEven的参数值域是偶数,而isOdd奇数。 (isEven orElse isOdd).apply(1)就既能处理偶数也能处理奇数,相当于把两个部分函数组合起来。

它包含其它的一些方法:

  • andThen: 对结果进一步处理,isEven.andThen(println)(2)
  • applyOrElse: isEven.applyOrElse(1,isOdd)
  • compose:和 andThen类似,但是先调用最后一个,再调用第一个。isEven.compose((x:Int) => x+2)(2) //4
  • lift:转换成一个正常的函数,isEven.lift(2),返回Option
  • orElse: 组合,扩大参数的值域
  • runWith:isEven.runWith(println)(2). 等价if(pf isDefinedAt x) { action(pf(x)); true } else false.返回结果类型为(A) ⇒ Boolean,这和andThen不同,andThen返回PartialFunction[A, C]