tutorial software examples blanquerna bayer scala

software - ¿Cómo puedo unir las clases en una declaración de "coincidencia" de Scala?



scala vs java (4)

Encontré el mismo problema y colocar la clase en un "identificador estable" no era tan práctico. Descubrí que lo mejor que se podía hacer era tener declaraciones ordenadas "si no".

Utilizando este método:

private def is[T <: AnyRef : Manifest](implicit cls: Class[_]) = cls == manifest[T].runtimeClass

Puedo escribir:

implicit val arg = cls if (is[ClassA]) ... else if (is[ClassB]) ... ... else throw new IllegalArgumentException("Unknown class: " + cls)

¿Cómo puedo usar una declaración de "coincidencia" para identificar el valor de una variable de clase? Lo siguiente no es válido y no puedo encontrar una variante aceptable, excepto si ... else if ... else ...

val c: Class[_] = classOf[Int] val what = c match { case classOf[Int] => "int!"; case classOf[Float] => "float!" }

El compilador se queja: error: not found: type classOf

Y, por supuesto, no puedo usar Class[Int] porque esa información de tipo se borra:

c match { case Class[Int] => "int!"; case Class[Float] => "float!" } error: type Class of type Class does not take type parameters.

También he probado variantes como Int.class , todo en vano. (Y realmente no quiero convertir a cadenas: creo que es importante que el compilador atrape el cambio de nombre / clases).

¿Estoy siendo denso o me he topado con un punto ciego de Scala?


La comparación de casos verbosa funciona:

val what = c match { case q if q == classOf[Int] => "int!" case q if q == classOf[Float] => "float!" }

Por supuesto, al ser un identificador en minúsculas, classOf no debería funcionar directamente en una declaración de caso de todos modos. Sin embargo, tampoco lo hace un escapado.

case `classOf`[Int]

trabaja en este caso, así que tendrás que ir con if -guard.


Para considerar la herencia:

val what = c match { case q if classOf[Int].isAssignableFrom(q) => "int!" case q if classOf[Float].isAssignableFrom(q) => "float!" }


Puede hacer coincidir los valores de clase si crea un identificador estable (es decir, un val) para ellos,

scala> val c: Class[_] = classOf[Int] c: Class[_] = int scala> val ClassOfInt = classOf[Int] ClassOfInt: java.lang.Class[Int] = int scala> val ClassOfFloat = classOf[Float] ClassOfFloat: java.lang.Class[Float] = float scala> val what = c match { | case ClassOfInt => "int!" | case ClassOfFloat => "float!" | } what: String = int!

Tenga en cuenta que no puede coincidir con el tipo (es decir, Clase [Int]) porque el borrado significa que las diferentes instancias de tipo de Clase [T] son ​​indistinguibles en el tiempo de ejecución ... de ahí la siguiente advertencia

scala> val what = c match { | case _: Class[Int] => "int!" | case _: Class[Float] => "float!" | } warning: there were 2 unchecked warnings; re-run with -unchecked for details what: java.lang.String = int!