Un ejemplo basado en el conocimiento TypeTag adquirida con la lectura de Scala: What is a TypeTag and how do I use it? Publicado por Eugene Burmako en los comentarios sobre su pregunta:
import scala.reflect.runtime.universe._
object ScalaApplication {
def main(args: Array[String]) {
printType(List(42))
printType(List("42"))
printType(List("42", 42))
}
def printType[T : TypeTag](t: T) {
println(typeOf[T])
}
}
Esto debería dar la salida:
$ scala ScalaApplication.scala
List[Int]
List[String]
List[Any]
[ACTUALIZACIÓN 1:]
Sin embargo, si quieres estar al tanto de tipo asignado a una referencia de tipo Any
puede que tenga que optar por algún tipo de tipo de envoltorio en cuenta:
import scala.reflect.runtime.universe._
object ScalaApplication {
def main(args: Array[String]) {
val anyWrapper = new AnyWrapper
List(1,2,3).foreach { i =>
i match {
case 1 => anyWrapper.any = 42
case 2 => anyWrapper.any = "a string"
case 3 => anyWrapper.any = true
}
print(anyWrapper.any)
print(" has type ")
println(anyWrapper.typeOfAny)
}
}
class AnyWrapper {
private var _any: Any = null
private var _typeOfAny: Type = null
def any = _any
def typeOfAny = _typeOfAny
def any_=[T: TypeTag](a: T) = {
_typeOfAny = typeOf[T]
_any = a
}
}
}
Esto debería dar la salida:
$ scala ScalaApplication.scala
42 has type Int
a string has type String
true has type Boolean
Pero esta solución aún no cubre el caso donde el tipo de referencia es desconocido en tiempo de compilación.
[ACTUALIZACIÓN 2:]
Si los tipos son emitidos de forma explícita a la referencia del tipo Any
, usted podría tener que enumerar todos los tipos posibles en un comunicado partido con el fin de recuperar el tipo:
import scala.reflect.runtime.universe._
object ScalaApplication {
def main(args: Array[String]) {
List(1,2,3).foreach { i =>
val any: Any = i match {
case 1 => 42.asInstanceOf[Any]
case 2 => "a string".asInstanceOf[Any]
case 3 => true.asInstanceOf[Any]
}
print(any)
print(" has type ")
println(matchType(any))
}
}
def matchType(any: Any) = {
any match {
case a: Int => typeOf[Int]
case a: String => typeOf[String]
case a: Boolean => typeOf[Boolean]
}
}
}
esto debería dar la salida:
$ scala ScalaApplication.scala
42 has type Int
a string has type String
true has type Boolean
Pero esta solución requiere que sepas (una nd list) todos los tipos posibles que podría recibir en el valor any
.
Quizás pueda encontrar una solución viable después de leer [esta respuesta] (http://stackoverflow.com/a/1094214/315306) – Raffaele
@Raffaele. Gracias por la referencia. Lamentablemente, la pregunta (y la respuesta) tratan el caso cuando los tipos son concretos y se conocen durante el tiempo de compilación. Los manifiestos ahora están en desuso, y los tipos de etiquetas (que reemplazan los manifiestos) requieren etiquetas concretas. –
Utilice AbsTypeTag (en RC1 renombrado a WeakTypeTag). Más información aquí: http://stackoverflow.com/questions/12218641/scala-2-10-what-is-a-typetag-and-how-do-i-use-it –