Scala PartialFunction构造具有不同的结果

时间:2013-10-01 16:45:03

标签: scala partialfunction

我正在尝试调试为什么某些部分功能组合不起作用时我注意到,根据你如何实例化部分功能,你会得到不同的结果。

当你使用语法糖方法时,它都按预期工作:

scala> val pf1:PartialFunction[Any,Unit] = {case "a" => println("AAA")}
pf1: PartialFunction[Any,Unit] = <function1>

scala> val pf2:PartialFunction[Any,Unit] = {case "b" => println("BBB")}
pf2: PartialFunction[Any,Unit] = <function1>

scala> val pf = pf1 orElse pf2
pf: PartialFunction[Any,Unit] = <function1>

scala> pf("a")
AAA

scala> pf("b")
BBB

但是,如果使用PartialFunction对象,它将不再起作用。

scala> val pf1 = PartialFunction[Any,Unit]{case "a" => println("AAA")}
pf1: PartialFunction[Any,Unit] = <function1>

scala> val pf2 = PartialFunction[Any,Unit]{case "b" => println("BBB")}
pf2: PartialFunction[Any,Unit] = <function1>

scala> val pf = pf1 orElse pf2
pf: PartialFunction[Any,Unit] = <function1>

scala> pf("a")
AAA

scala> pf("b")
scala.MatchError: b (of class java.lang.String)
at $anonfun$1.apply(<console>:7)

为什么?您通常会期望Object的apply方法的行为类似于Class的构造函数。

3 个答案:

答案 0 :(得分:3)

文档说Object的apply方法将普通函数转换为部分函数,​​但它没有详细说明。显然,isDefinedAt始终返回true

scala> val pf1 = PartialFunction[Any,Unit]{case "a" => println("AAA")}
pf1: PartialFunction[Any,Unit] = <function1>

scala> pf1.isDefinedAt("a")
res14: Boolean = true

scala> pf1.isDefinedAt("b")
res15: Boolean = true

这将导致pf1始终捕获输入。所以我猜结论是小心如何实例化部分函数

答案 1 :(得分:0)

PartialFunction Object中的apply方法将普通函数转换为部分函数。阅读文档here因此,声明的部分函数被视为普通函数并输入为PartialFunction。无论在那里实现什么,该函数的域都成为普通函数的所有域。因此,pf1最终消耗所有输入并且从不调用orElse函数。

答案 2 :(得分:0)

正如其他人所指出的,PartialFunction.apply将普通函数转换为部分函数。

这是唯一合理的方法,因为普通函数的域是未知的(就PartialFunction.apply而言),是创建一个定义在任何地方的部分函数。

因此,当您编写PartialFunction[Any,Unit] { case "a" => println("AAA") }时,您实际上正在创建两个部分函数:传递到apply方法的函数和apply返回的函数} 方法。它们几乎相同,只是返回的函数在任何地方定义,而不仅仅是"a"