Cela peut vous aider:
class Matches(m: Any) {
def matches[R](f: PartialFunction[Any, R]) { if (f.isDefinedAt(m)) f(m) }
}
implicit def any2matches(m: Any) = new Matches(m)
scala> 'c' matches { case x: Int => println("Int") }
scala> 2 matches { case x: Int => println("Int") }
Int
Maintenant, quelques explications sur la nature générale du problème.
Où peut un match se produire?
Il y a trois endroits où la correspondance de modèle qui pourrait arriver: val
, case
et for
. Les règles sont les suivantes:
// throws an exception if it fails
val pattern = value
// filters for pattern, but pattern cannot be "identifier: Type",
// though that can be replaced by "id1 @ (id2: Type)" for the same effect
for (pattern <- object providing map/flatMap/filter/withFilter/foreach) ...
// throws an exception if none of the cases match
value match { case ... => ... }
Il est, cependant, une autre situation où l' case
peuvent apparaître, ce qui est la fonction et la fonction partielle de littéraux. Par exemple:
val f: Any => Unit = { case i: Int => println(i) }
val pf: PartialFunction[Any, Unit] = { case i: Int => println(i) }
Les deux fonctions et partielles des fonctions de lever une exception si elle est appelée avec un argument qui ne correspond à aucune de l'affaire états. Cependant, partielle fonctions fournissent également une méthode appelée isDefinedAt
qui peut tester si un match ne peut être faite ou non, ainsi que d'une méthode appelée lift
, ce qui permettra de tourner PartialFunction[T, R]
en Function[T, Option[R]]
, ce qui signifie non-correspondance des valeurs en None
au lieu de lancer une exception.
Qu'est ce qu'un match?
Un match est une combinaison de plusieurs tests différents:
// assign anything to x
case x
// only accepts values of type X
case x: X
// only accepts values matches by pattern
case x @ pattern
// only accepts a value equal to the value X (upper case here makes a difference)
case X
// only accepts a value equal to the value of x
case `x`
// only accept a tuple of the same arity
case (x, y, ..., z)
// only accepts if extractor(value) returns true of Some(Seq()) (some empty sequence)
case extractor()
// only accepts if extractor(value) returns Some something
case extractor(x)
// only accepts if extractor(value) returns Some Seq or Tuple of the same arity
case extractor(x, y, ..., z)
// only accepts if extractor(value) returns Some Tuple2 or Some Seq with arity 2
case x extractor y
// accepts if any of the patterns is accepted (patterns may not contain assignable identifiers)
case x | y | ... | z
Maintenant, les extracteurs sont les méthodes d' unapply
ou unapplySeq
, la première revenant Boolean
ou Option[T]
, et le deuxième retour Option[Seq[T]]
où None
signifie qu'aucune correspondance n'est fait, et Some(result)
va essayer de faire correspondre result
comme décrit ci-dessus.
Donc, il ya toutes sortes de syntaxique solutions, qui ne sont tout simplement pas possible sans l'utilisation de l'un des trois constructions où le motif correspond peut arriver. Vous pouvez émuler certaines fonctionnalités, comme la valeur de l'égalité et des extracteurs, mais pas tous d'entre eux.