Me pregunto cómo puedo utilizar la coincidencia de patrones de varios tipos. Yo tengo:
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()
}
Entonces me gustaría escribir algo como:
x match {
case a @ (MyFirst | MySecond) => doSomething()
case _ => doSomethingElse()
}
Vi una construcción similar en algún tutorial, pero me da un error:
pattern type is incompatible with expected type;
[error] found : object MyFirst
[error] required: MyAbstract
Entonces, ¿hay alguna manera de definir algunos tipos diferentes en la cláusula on case? Creo que haría el código más bonito. Como si tuviera 5 de ellos, escribiré el mismo código 5 veces (llamando a doSomething ()).
¡Gracias por adelantado!
scala
types
pattern-matching
psisoyev
fuente
fuente
doSomething
casos, ¿por qué no coincidir con elcase a : MyAbstract
entonces ...?Respuestas:
Falta el paréntesis para sus clases de casos. Las clases de casos sin listas de parámetros están en desuso.
Prueba esto:
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 tiene demasiados parámetros para sus clases de casos y no le gusta tener que escribir
Foo(_,_,..)
patrones largos , entonces tal vez:x match { case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB) case _ => doSomethingElse() }
O solo:
x match { case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB case _ => doSomethingElse(x) }
¿Pero quizás solo querías objetos de caja 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() }
fuente
obj @ (_: MyFirst | _: MySecond)
?obj
en los casos en los que lo estoy usando en unadoSomething
llamada. En mi caso, la llamada dedoSomething
no se estaba usandoobj
, así que no la necesito. Pero de todos modos, ¡gracias por tu comentario!