我认为这段代码不应该工作,但它确实起作用(在Scala 2.10中):
scala> ((i: Int) => i.toString match {
| case s if s.length == 2 => "A two digit number"
| case s if s.length == 3 => "A three digit number"
| }): PartialFunction[Int,String]
res0: PartialFunction[Int,String] = <function1>
// other interactions omitted
scala> res0.orElse(PartialFunction((i: Int) => i.toString))
res5: PartialFunction[Int,String] = <function1>
scala> res5(1)
res6: String = 1它怎麽工作?我希望在MatchError中抛出一个res0。
Scala语言规范似乎没有显式地记录应该如何解释res0。
发布于 2013-11-14 21:04:17
诀窍是编译器并没有把你的定义解释为一个转换成部分函数的函数--它实际上是首先创建一个部分函数。您可以通过注意res0.isDefinedAt(1) == false来验证。
如果您实际将一个总函数转换为一个部分函数,您将得到您期望的行为:
scala> PartialFunction((i: Int) => i.toString match {
| case s if s.length == 2 => "A two digit number"
| case s if s.length == 3 => "A three digit number"
| })
res0: PartialFunction[Int,String] = <function1>
scala> res0 orElse ({ case i => i.toString }: PartialFunction[Int, String])
res1: PartialFunction[Int,String] = <function1>
scala> res1(1)
scala.MatchError: 1 (of class java.lang.String)
// ...在本例中,PartialFunction.apply将其参数视为一个总体函数,因此任何有关其定义位置的信息都会丢失。
发布于 2013-11-14 08:53:58
orElse是在PartialFunction上定义的,因此在未定义原始参数的情况下,参数被视为回退。见API。
发布于 2013-11-14 08:50:39
您说,如果res0不匹配,则需要尝试另一个pf。从本质上讲,这是如何工作的:
if (res0.isDefinedAt(1)) {
res0(1)
} else {
other(1)
}orElse调用创建了一个OrElse实例,该实例继承自PartialFunction:https://github.com/scala/scala/blob/master/src/library/scala/PartialFunction.scala#L159
当您现在在此apply上调用OrElse时,它将调用f1.applyOrElse(x, f2):https://github.com/scala/scala/blob/master/src/library/scala/PartialFunction.scala#L162
这将调用if (isDefinedAt(x)) apply(x) else f2(x):https://github.com/scala/scala/blob/master/src/library/scala/PartialFunction.scala#L117-L118
因此,您只会得到一个MatchError,当两个pf的匹配。
https://stackoverflow.com/questions/19973026
复制相似问题