99 votes

Correspondance de types multiples en Scala

Je me demande comment utiliser le filtrage par types multiples. 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 un tutoriel, mais cela me donne une erreur :

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

Existe-t-il un moyen de définir plusieurs types différents dans une clause de cas ? Je pense que cela rendrait le code plus joli. Comme si j'en avais 5, j'écrirais le même code 5 fois (en appelant doSomething()).

Merci d'avance !

167voto

Faiz Points 8115

Il vous manque la parenthèse pour vos classes de cas. Les classes de cas sans liste de paramètres sont dépréciées.

Essayez ç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 avoir à écrire de longs Foo(_,_,..) des modèles, 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 vouliez-vous simplement des objets de cas singletons ?

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X