首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala中的魔术PartialFunction

Scala中的魔术PartialFunction
EN

Stack Overflow用户
提问于 2013-11-14 08:40:20
回答 3查看 275关注 0票数 3

我认为这段代码不应该工作,但它确实起作用(在Scala 2.10中):

代码语言:javascript
复制
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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-14 21:04:17

诀窍是编译器并没有把你的定义解释为一个转换成部分函数的函数--它实际上是首先创建一个部分函数。您可以通过注意res0.isDefinedAt(1) == false来验证。

如果您实际将一个总函数转换为一个部分函数,您将得到您期望的行为:

代码语言:javascript
复制
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将其参数视为一个总体函数,因此任何有关其定义位置的信息都会丢失。

票数 3
EN

Stack Overflow用户

发布于 2013-11-14 08:53:58

orElse是在PartialFunction上定义的,因此在未定义原始参数的情况下,参数被视为回退。见API

票数 2
EN

Stack Overflow用户

发布于 2013-11-14 08:50:39

您说,如果res0不匹配,则需要尝试另一个pf。从本质上讲,这是如何工作的:

代码语言:javascript
复制
if (res0.isDefinedAt(1)) {
  res0(1)
} else {
  other(1)
}

orElse调用创建了一个OrElse实例,该实例继承自PartialFunctionhttps://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的匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19973026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档