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?

有帮助吗?

解决方案

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
  }
}

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top