metodos lenguaje introduccion ejemplos colecciones codigos scala pattern-matching

lenguaje - ¿Cómo se combinan los patrones de las grandes clases de casos de Scala?



scala introduccion (2)

Considere la siguiente clase de caso de Scala:

case class WideLoad(a: String, b: Int, c: Float, d: ActorRef, e: Date)

La coincidencia de patrones me permite extraer un campo y descartar otros, así:

someVal match { case WideLoad(_, _, _, d, _) => d ! SomeMessage(...) }

Lo que me gustaría hacer, y lo que es más relevante cuando una clase de caso tiene ~ 20 campos impares, es extraer solo algunos valores de una manera que no implique escribir WideLoad(_, _, _, _, _, some, _, _, _, thing, _, _, interesting) .

Esperaba que los args nombrados pudieran ayudar aquí, aunque la siguiente sintaxis no funciona:

someVal match { case WideLoad(d = dActor) => dActor ! SomeMessage(...) // ^---------- does not compile }

¿Hay alguna esperanza aquí, o estoy atascado tipeando muchos, muchos _, _, _, _ ?

EDITAR : Entiendo que puedo hacer el case wl @ WideLoad(...whatever...) => wl.d , pero aún me pregunto si hay incluso una sintaxis de terser que haga lo que necesito sin tener que introducir un valor adicional .


No sé si esto es apropiado, pero también puedes construir un objeto para que coincida con ese campo, o ese conjunto de campos (código no probado):

object WideLoadActorRef { def unapply(wl: WideLoad): Option[ActorRef] = { Some(wl.d) } } someVal match { case WideLoadActorRef(d) => d ! someMessage }

o incluso

object WideLoadBnD { def unapplySeq(wl: WideLoad): Option[(Int,ActorRef)] = { Some((wl.b,wl.d)) } } someVal match { case WideLoadBnD(b, d) => d ! SomeMessage(b) }


Siempre puedes recurrir a los guardias. No es realmente agradable, pero es mejor que la coincidencia de patrones normales para tus clases de casos de monstruos :-P

case class Foo(a:Int, b:Int, c:String, d:java.util.Date) def f(foo:Foo) = foo match { case fo:Foo if fo.c == "X" => println("found") case _ => println("arrgh!") } f(Foo(1,2,"C",new java.util.Date())) //--> arrgh! f(Foo(1,2,"X",new java.util.Date())) //--> found

Dicho esto, creo que deberías reconsiderar tu diseño. Probablemente pueda agrupar lógicamente algunos parámetros utilizando clases de casos, tuplas, listas, conjuntos o mapas. Scala admite la coincidencia de patrones anidados:

case class Bar(a: Int, b:String) case class Baz(c:java.util.Date, d:String) case class Foo(bar:Bar, baz:Baz) def f(foo:Foo) = foo match { case Foo(Bar(1,_),Baz(_,"X")) => println("found") case _ => println("arrgh!") } f(Foo(Bar(1,"c"),Baz(new java.util.Date, "X"))) //--> found f(Foo(Bar(1,"c"),Baz(new java.util.Date, "Y"))) //--> arrgh!