¿Cómo lanzo una variable en Scala?

199

Dada una variable con tipo Graphics, ¿cómo la Graphics2Dconvierto en Scala?

Eugene Yokota
fuente

Respuestas:

282

La técnica preferida es utilizar la coincidencia de patrones. Esto le permite manejar con gracia el caso de que el valor en cuestión no sea del tipo dado:

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

Este bloque reproduce la semántica del asInstanceOf[Graphics2D]método, pero con mayor flexibilidad. Por ejemplo, podría proporcionar diferentes ramas para varios tipos, realizando efectivamente múltiples lanzamientos condicionales al mismo tiempo. Finalmente, realmente no necesita lanzar una excepción en el área general, también podría regresar null(o preferiblemente None), o podría ingresar a alguna rama alternativa que funcione sinGraphics2D .

En resumen, este es realmente el camino a seguir. Es un poco más sintácticamente voluminoso que asInstanceOf, pero la flexibilidad adicional casi siempre vale la pena.

Daniel Spiewak
fuente
19
+1 porque es interesante, pero demasiado para este escenario. no es asi
Eugene Yokota
¿Qué sucede si ya hice una coincidencia de patrón pero perdí la referencia al valor emitido: <code> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .something (value)} </code>, hay una manera de obtener ' ¿base 'fundido a MyConcrete incluso si desea extraer el "valor" explotando la llamada' no aplicada 'realizada por "case MyConcrete (value)"?
ithkuil
44
Prueba esto: base match { case base @ MyConcrete(value) => base.something(value) } Obviamente, el sombreado basees opcional. Podría usar fácilmente un nombre de variable diferente.
Daniel Spiewak
Lo que no entiendo es ¿cómo obtendrías el resultado de esta conversión de coincidencia de patrones en una variable? como en java si fuera String a = (String) b; ¿Cuál sería el equivalente de escala?
James McMahon
@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith
224
g.asInstanceOf[Graphics2D];
Eugene Yokota
fuente
36
Una vez que me acostumbré a Scala, aprendí a no usarlo asInstanceOf, ya que frustra el propósito de tener un sistema de tipo estático y se siente asqueroso.
Eugene Yokota
26
Desafortunadamente, esta es una operación común cuando se usa Swing. Para operaciones de pintura personalizadas, debe anular el método 'public void paintComponent (Graphics g)'. El parámetro Graphics es en realidad una instancia de Graphics2D, pero se necesita una conversión. La versión de coincidencia de patrones es probablemente más verbosidad que garantizada. Recuerde: ¡Evite de forma seductora la hiperverbosidad y la prolijidad ofuscadoras!
hohonuuli
77
@hohonuuli Creo que el elenco está bien en ese caso específico, pero si usa scala-swingcomponentes, el parámetro de paintComponent ya es Graphics2D, por lo que no se requiere elenco
Luigi Plinge
2
¿Por qué es tan largo? ¿Por qué "asInstanceOf cuando solo puede ser" como "o" asof "palabra clave o método? ¿O por qué no simplemente adoptaron la forma C ++ y Java como una opción porque eso es convencional y no hay un gran problema con eso?
LEMUEL ADANE
16
@LemuelAdane El hecho de que estés usando yesos es un olor a código, no tiene sentido hacerlos más fáciles.
Daenyth