0

我试图调试为什么某些部分函数组合不起作用,当我注意到取决于您实例化部分函数的方式,您会得到不同的结果。

当您使用语法糖方法时,一切都按预期工作:

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 的构造函数。

4

3 回答 3

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始终捕获输入。所以我想结论是要小心你如何实例化一个部分函数

于 2013-10-01T16:45:02.963 回答
0

PartialFunction 对象中的 apply 方法将普通函数转换为部分函数。在这里阅读文档因此声明的部分函数被视为普通函数并键入为 PartialFunction。这个函数的域变成了一个普通函数的所有域,不管在那里实现了什么。因此,pf1 最终消耗了所有输入并且从不调用 orElse 函数。

于 2013-10-01T17:28:06.337 回答
0

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

由于普通函数的域是未知的(就目前PartialFunction.apply而言),唯一合理的方法是创建一个在各处定义的偏函数。

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

于 2013-10-01T21:33:19.423 回答