web-dev-qa-db-fra.com

Scala correspondance de modèles multiples)

Je me demande comment puis-je utiliser plusieurs types de correspondance de modèles? J'ai:

abstract class MyAbstract

case class MyFirst extends MyAbstract
case class MySecond extends MyAbstract
case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething()

val x: MyAbstract = MyFirst

x match { 
 case a: MyFirst => doSomething()
 case b: MySecond => doSomething()
 case _ => doSomethingElse()
}

Donc, j'aimerais écrire quelque chose comme:

x match {
 case a @ (MyFirst | MySecond) => doSomething()
 case _ => doSomethingElse()
}

J'ai vu une construction similaire dans certains tutoriels, mais cela me donne une erreur:

pattern type is incompatible with expected type;
[error]  found   : object MyFirst
[error]  required: MyAbstract

Alors, y a-t-il moyen de définir quelques types différents dans la clause on case? Je pense que cela rendrait le code plus joli. Comme si j'en aurais 5, j'écrirai le même code 5 fois (en appelant doSomething ()).

Merci d'avance!

63
psisoyev

Il vous manque la parenthèse pour vos classes de cas. Les classes de cas sans listes de paramètres sont obsolètes.

Essaye ça:

abstract class MyAbstract
case class MyFirst() extends MyAbstract
case class MySecond() extends MyAbstract

val x: MyAbstract = MyFirst()


x match {
   case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB)
   case _ => doSomethingElse()
}

Si vous avez trop de paramètres pour vos classes de cas et que vous n'aimez pas écrire de longs modèles Foo(_,_,..), alors peut-être:

x match {
   case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB)
   case _ => doSomethingElse()
}

Ou juste:

x match {
   case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB
   case _ => doSomethingElse(x)
}

Mais peut-être que vous vouliez juste des objets singleton?

abstract class MyAbstract
case object MyFirst extends MyAbstract
case object MySecond extends MyAbstract

val x: MyAbstract = MyFirst

x match {
   case aOrB @ (MyFirst | MySecond) => doSomething()
   case _ => doSomethingElse()
}
116
Faiz