texto significa razonamiento qué que palabra mensaje indice implícito implícita implicito implicita explícitos explícito ejemplos ejemplo conocimiento scala

scala - significa - Clase de caso y argumentos implícitos y coincidencia de patrones



razonamiento implicito (2)

Intenté combinar argumentos implícitos con clases de casos, pero me quedé atascado.

case class C(i: Int)(implicit b: Boolean) val c1 = C(1)(true) implicit val b = true val c2 = C(2) c1 match { case C(i)(b) => // doesn´t work case C(i,b) => // doesn´t work case C(i) => // works, but wanted: if (b) i else 0 }

De acuerdo con la especificación del lenguaje Scala, se debe al objeto extractor generado por el compilador para las clases de caso: Mi Boolean implícito no es un miembro de la clase de caso resultante, por lo que tiene que estar en la segunda lista de argumentos (implícita) (que puedo "No se encuentra en el método de aplicación de los objetos complementarios, desafortunadamente):

Una definición de clase de caso de c[tps](ps1 ). . .(psn) c[tps](ps1 ). . .(psn) c[tps](ps1 ). . .(psn) con los parámetros de tipo tps y los parámetros de valor ps genera implícitamente un objeto extractor (§8.1.8) que se define de la siguiente manera:

object c { def apply[tps](ps1 ). . .(psn): c[tps] = new c[Ts](xs1 ). . .(xsn) def unapply[tps](x: c[tps]) = if (x eq null) scala.None else scala.Some(x.xs11, . . . , x.xs1k) }

¿Cómo puedo definir una clase de caso con miembros que se suministran implícitamente en el momento de la creación?


La respuesta de Alex es inteligente, sin embargo, no me gusta mucho _ en el nombre del objeto, me parece que la sintaxis es un poco extraña y recordar que el subrayado hace que la comparación de patrones sea más difícil de usar. (Por supuesto, todo esto es subjetivo, por lo que sus sentimientos pueden variar).

Mi primer enfoque para lidiar con esto fue mover los parámetros implícitos al método de apply en el objeto compañero.

case class A(i: Int, b: Boolean) object Foo { def apply(i: Int)(implicit b: Boolean): Foo = apply(a, b) }

Pero esto resulta en

Error:(21, 14) double definition: method apply:(i: Int, b: Boolean)com.workday.cloud.master.package.A and method apply:(i: Int)(implicit b: Boolean)com.workday.cloud.master.package.A at line 24 have same type after erasure: (i: Int, b: Boolean)com.workday.cloud.master.package.A case class A(i: Int, b: Boolean) ^

Como sugirió mi amigo Yuriy, podemos solucionar esto agregando un parámetro implícito Unused adicional.

object A { implicit object Unused def apply(i: Int)(implicit b: Boolean, unused: Unused.type): A = apply(i, b) }

El enfoque que elija depende de usted. Creo que este enfoque permite que el código de mi cliente se vea más natural.


Puede definir una clase de caso con argumentos implícitos, pero como ha descubierto, no están disponibles para la coincidencia de patrones. Aunque siempre puedes escribir tu propio extractor:

case class C(i: Int)(implicit val b: Boolean) // You can''t call this C because that seat is taken (can''t overload the default unapply) object C_ { // In order to be able to select `b` here, // it needs to be declared as "implicit *val* b: Boolean" def unapply(in: C) = Some((in.i, in.b)) } c1 match { case C_(i, b) => ... }