trait PartialFunction[-A, +B] extends (A => B) {
def isDefinedAt(x: A): Boolean
}
g 函数被编译器展开如下:
new PartialFunction[String, String] {
def apply(x: String) = x match {
case "ping" => "pong"
}
def isDefinedAt(x: String) = x match {
case "ping" => true
case _ => false
}
}
但注意,isDefinedAt 返回 true 并不意味着万事大吉,例如:
val g: PartialFunction[List[Int], String] = {
case Nil => "one"
case x :: rest =>
rest match {
case Nil => "two"
}
}
上面例子中,g.isDefinedAt(List(1, 2, 3)) 返回 true,但是实现调用时,函数将抛出异常,该例说明 PartialFunction 只能匹配最外层的 case 表达式,内层无法顾忌,从而内层可能因为各种各样的原因抛出异常。
使用
case
表达式可以实现偏函数:f
函数被编译器展开如下:可以看到,如果使用
Pong
调用f
会抛出异常,因为f
定义域并非全部String
,可以将其类型修改为偏函数:偏函数可以使用
isDefinedAt
判断参数是否在偏函数定义域上,从而避免抛出异常,而PartialFunction
定义如下:g
函数被编译器展开如下:但注意,
isDefinedAt
返回true
并不意味着万事大吉,例如:上面例子中,
g.isDefinedAt(List(1, 2, 3))
返回true
,但是实现调用时,函数将抛出异常,该例说明PartialFunction
只能匹配最外层的case
表达式,内层无法顾忌,从而内层可能因为各种各样的原因抛出异常。