2012-06-28 5 views
6

Con el método isInstanceOf, se puede verificar el tipo de un objeto. Por ejemplo:¿Cómo se muestran todos los tipos de un objeto (en Scala)?

scala> val i: Int = 5 
i: Int = 5 

scala> val a: Any = i 
a: Any = 5 

scala> a.isInstanceOf[Any] 
res0: Boolean = true 

scala> a.isInstanceOf[Int] 
res1: Boolean = true 

scala> a.isInstanceOf[String] 
res2: Boolean = false 

¿Cómo se pueden mostrar todos los tipos de un objeto (si es posible?)?

Respuesta

6

Usted puede hacer esto con bastante facilidad en 2,10 (M4 o posterior):

import scala.reflect.runtime.universe._ 

def superTypes(t: Type): Set[Type] = 
    (t.parents ++ t.parents.flatMap(superTypes)).toSet 

def allTypes[A](a: A)(implicit tag: TypeTag[A]) = superTypes(tag.tpe) + tag.tpe 

que nos da lo siguiente:

scala> allTypes(1).foreach(println) 
AnyVal 
Any 
NotNull 
Int 

scala> allTypes("1").foreach(println) 
String 
Any 
Object 
Comparable[String] 
CharSequence 
java.io.Serializable 

scala> allTypes(List("1")).foreach(println) 
scala.collection.LinearSeq[String] 
scala.collection.GenSeq[String] 
scala.collection.IterableLike[String,List[String]] 
scala.collection.GenIterable[String] 
scala.collection.GenTraversableLike[String,Iterable[String]] 
... 

Vas a tener un tiempo mucho más difícil tratar de hacer algo como este antes de 2.10.

+0

Gracias, con 2.10 se ve de hecho bastante fácil. ¿Sabes si es posible enumerar todos los tipos en pre-2.10? –

+0

[Manifests] (http://www.scala-lang.org/api/current/scala/reflect/Manifest.html) no están diseñados para admitir este tipo de cosas. Puede usar la [API de Reflection de Java] (http://docs.oracle.com/javase/tutorial/reflect/index.html) para obtener superclases, interfaces implementadas, etc., pero eso es muy diferente de obtener los _types_. –

1

Aquí hay otra solución, que hace uso del método baseType para reificar el parámetro de tipo.

import scala.reflect.runtime.universe._ 

def typesOf[T : TypeTag](v: T): List[Type] = 
    typeOf[T].baseClasses.map(typeOf[T].baseType) 

Ejemplo:

scala> typesOf("1") foreach println 
String 
CharSequence 
Comparable[String] 
java.io.Serializable 
Object 
Any 
+0

'baseClasses' es práctico, pero esos no son _types_, por supuesto, que es lo que la pregunta solicitada. También vale la pena señalar que esto no funcionará antes de 2.10. –

+0

@TravisBrown La pregunta dice _display_ todos los tipos. Lo que 'baseClasses' devuelve es el' Symbol' para los tipos. Puede llamar 'asTypeSymbol' en todos ellos, o, por supuesto,' .asType' o '.typeSignature'. –

+0

Pero supongamos, por ejemplo, que desea los tipos de 'List (" 1 ")' de modo que pueda saber si 'GenSeq [String]' es uno de ellos (sin usar 'isInstanceOf' por ningún motivo). Una vez que haya usado 'baseClasses' no hay forma de obtener esa información; todo lo que puede hacer es obtener el símbolo de tipo para' GenSeq'. –

Cuestiones relacionadas