问题
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 MatchError
occurs 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