scala – orElse如何处理PartialFunctions
使用PartialFunction上定义的orElse方法,我得到了非常奇怪的行为(至少在我看来)
在我看来: val a = PartialFunction[String,Unit] { case "hello" => println("Bye") } val b: PartialFunction[Any,Unit] = a.orElse(PartialFunction.empty[Any,Unit]) a("hello") // "Bye" a("bogus") // MatchError b("bogus") // Nothing b(true) // Nothing 有道理,但这不是它的表现方式,我很难理解为什么类型签名似乎表明我在上面暴露了什么. 以下是我使用Scala 2.11.2观察的内容的记录: Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM,Java 1.8.0_11). Type in expressions to have them evaluated. Type :help for more information. scala> val a = PartialFunction[String,Unit] { | case "hello" => println("Bye") | } a: PartialFunction[String,Unit] = <function1> scala> a("hello") Bye scala> a("bye") scala.MatchError: bye (of class java.lang.String) at $anonfun$1.apply(<console>:7) at $anonfun$1.apply(<console>:7) at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242) at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) ... 33 elided scala> val b = a.orElse(PartialFunction.empty[Any,Unit]) b: PartialFunction[String,Unit] = <function1> scala> b("sdf") scala.MatchError: sdf (of class java.lang.String) at $anonfun$1.apply(<console>:7) at $anonfun$1.apply(<console>:7) at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242) at scala.PartialFunction$OrElse.apply(PartialFunction.scala:162) ... 33 elided 请注意val b的返回类型,它没有扩展PartialFunction的类型. 但这也不能按预期工作: scala> val c = a.orElse(PartialFunction.empty[String,Unit]) c: PartialFunction[String,Unit] = <function1> scala> c("sdfsdf") scala.MatchError: sdfsdf (of class java.lang.String) at $anonfun$1.apply(<console>:7) at $anonfun$1.apply(<console>:7) at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242) at scala.PartialFunction$OrElse.apply(PartialFunction.scala:162) ... 33 elided 解决方法
你的尝试有一些问题,但首先让我们看看一个有效的实现:
scala> val a: PartialFunction[String,Unit] = { case "hello" => println("bye") } a: PartialFunction[String,Unit] = <function1> scala> val b: PartialFunction[Any,Unit] = { case _ => println("fallback") } b: PartialFunction[Any,Unit] = <function1> scala> val c = a.orElse(b) c: PartialFunction[String,Unit] = <function1> scala> c("hello") bye scala> c("foo") fallback 您的代码中存在两个主要错误: >定义PF的方式 1.如何定义PartialFunction val right: PartialFunction[String,Unit] = { case "hello" => println("bye") } 如何定义它: val wrong = PartialFunction[String,Unit] { case "hello" => println("bye") } 如果你看一下PartialFunction.apply的定义 def apply[A,B](f: A => B): PartialFunction[A,B] = { case x => f(x) } 你会看到它定义了任何x的部分函数,??它将给定的f函数应用于它.现在你的{case“hello”=> println(“bye”)}是f参数,所以你最终得到以下(明显意外的)PartialFunction: val wrong: PartialFunction[String,Unit] = { case x => x match { case "hello" => println("bye") } 因此,当您询问它是否已定义时,它将始终返回true,因为它是为任何字符串定义的: wrong.isDefinedAt("hello") // true (ok) wrong.isDefinedAt("whatever") // true (sure?) 但是当你尝试应用它时 wrong("hello") // bye (ok) wrong("whatever") // MatchError (BOOM!) 你不能完成内心的比赛. 由于orElse决定是否根据isDefined的结果调用“else”,因此很明显它失败的原因. 空无所事! 直接从docs:
您正在寻找的PartialFunction(好吧,它不再是部分的)是: val fallback: PartialFunction[Any,Unit] = { case _ => println("fallback") } 或 – 只是为了表明我们从错误中吸取教训 – val fallback = PartialFunction[Any,Unit] { _ => println("fallback") } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |