偏函数
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 1 => " is even"
}
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 0 => " is odd"
}
(1 to 10) map (isEven orElse isOdd) foreach println
try {
(1 to 10) map isEven foreach println
} catch {
case _: MatchError => "Error!"
}
isEven.isDefineAt(2) //false
isOdd.isDefineAt(2) //true
val printResult: PartialFunction[String, Unit] = {
case x: String => println("result is: " + x)
}
(isEven andThen printResult)(3) //result is: 3 is even
偏函数是一个单参数函数,且并未对该类型的所有值都实现相应处理逻辑。偏函数的字面量语法由包围在花括号中的一个或多个case语句构成。这与普通函数字面量不同,普通函数字面量可以使用花括号,也可以使用圆括号。
偏函数之所以“偏”,在就在于其只能处理那些能与至少一个case语句匹配的输入,而不能处理所有可能的输入。
如果偏函数被调用,而函数的输入却与所有case语句都不匹配,系统就会抛出一个MatchError的运行时错误。可以使用isDefinedAt方法测试特定输入是否与偏函数匹配,这样偏函数就可以避免抛出MatchError错误了。
将多个偏函数连接成一个偏函数的方法有两种:
1. 使用orElse关键字,此时如果第一个偏函数不匹配就会尝试匹配下一个偏函数。
2. 使用andThen关键字,此时会将第一个偏函数的执行结果传递给下一个偏函数作为参数并执行第二个偏函数。
偏应用函数
def cat(s1: String)(s2: String): String = s1 + s2
val hello = cat("hello ") _ //定义一个偏应用函数
偏应用函数是一个表达式,包含函数的部分而非全部参数列表。返回值是一个新函数,此函数携带剩下的参数列表。
对于拥有多个参数列表的函数而言,如果你希望忽略其中一个或多个参数列表,可以通过定义一个新函数来实现。也就是说,你给出了部分所需要的参数。为了避免潜在的表达式歧义,Scala要求在后面加上下划线,用来告诉编译器你的真实目的。注意,这个特性只对函数的多个参数列表有效,对一个参数列表中的多个参数的情况并不适用。
参考《Scala程序设计》第二版