PartialFunction and MatchError

耗尽温柔 提交于 2019-12-10 20:46:32

问题


There are two ways to define PF: 1) with literal case {} syntax and 2) as explicit class. I need the following function throw a MatchError, but in the second case that doesn't happen.

1) with case

val test: PartialFunction[Int, String] =  {
  case x if x > 100 => x.toString
}

2) as class

val test = new PartialFunction[Int, String] {
  def isDefinedAt(x: Int) = x > 100
  def apply(x: Int) = x.toString
}

Should i, in the seconds case, manually call isDefinedAt, shouldn't it be called implicitly by the compiler?


回答1:


You will have to call isDefinedAt manually in your apply method:

val test = new PartialFunction[Int, String] {
  def isDefinedAt(x: Int) = x > 100
  def apply(x: Int) = if(isDefinedAt(x)) x.toString else throw new MatchError(x)
}

If you want to avoid this code, you can simply use the first way to define your partial function. It is syntactic sugar and will result in a valid definition of both isDefinedAt and apply. As described in the Scala language specification, your first definition will expand to the following:

val test = new scala.PartialFunction[Int, String] {
  def apply(x: Int): String = x match {
    case x if x > 100 => x.toString
  }
  def isDefinedAt(x: Int): Boolean = {
    case case x if x > 100 => true
    case _ => false
  }
}



回答2:


isDefinedAt is not a guard: it is not checked whenever you call the PartialFunction.

In your first case, the MatchErroroccurs because of the pattern matching failure. Actually, you can find out how the Partialfunction is built in the first case in the §8.5 of the Scala Specification.

In the second case, apply is defined for all x and then your definition of isDefinedAt is not valid.



来源:https://stackoverflow.com/questions/17806246/partialfunction-and-matcherror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!