2012-06-28 38 views
6

Con il metodo isInstanceOf, è possibile verificare il tipo di un oggetto. Per esempio:Come visualizzare tutti i tipi di oggetto (in 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 

Come si può visualizzare tutti i tipi di un oggetto (se è possibile a tutti?)?

risposta

6

È possibile farlo abbastanza facilmente a 2.10 (M4 o successiva):

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 

che ci dà la seguente:

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]] 
... 

Avrete un tempo molto più difficile cercare di fare qualcosa come questo pre-2.10.

+0

Grazie, con 2,10 sembra davvero abbastanza facile. Sai se è possibile elencare tutti i tipi in pre-2.10? –

+0

[Manifests] (http://www.scala-lang.org/api/current/scala/reflect/Manifest.html) non sono progettati per supportare questo tipo di cose. Potresti usare [Java Reflection API] (http://docs.oracle.com/javase/tutorial/reflect/index.html) per ottenere superclassi, interfacce implementate, ecc., Ma è molto diverso da ottenere _types_. –

1

Ecco un'altra soluzione, che utilizza il metodo baseType per reificare il parametro type.

import scala.reflect.runtime.universe._ 

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

Esempio:

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

'baseClasses' è comodo, ma quelli non sono _types_, ovviamente, che è quello che la domanda ha richiesto. Vale anche la pena notare che questo non funzionerà prima di 2.10. –

+0

@TravisBrown La domanda dice _display_ tutti i tipi. I ritorni di 'baseClasses' sono' Symbol' per i tipi. Puoi chiamare 'asTypeSymbol' su tutti loro, o, ovviamente,' .asType' o '.typeSignature'. –

+0

Diciamo per esempio che volete i tipi di 'List (" 1 ")' tali da poter sapere se 'GenSeq [String]' è uno di questi (senza usare 'isInstanceOf' per qualsiasi motivo). Una volta che hai usato 'baseClasses' non c'è modo di ottenere quell'informazione-tutto ciò che puoi fare è ottenere il simbolo del tipo per' GenSeq'. –

Problemi correlati