【问题标题】:How to display all types of an object (in Scala)?如何显示所有类型的对象(在 Scala 中)?
【发布时间】:2012-06-30 05:05:47
【问题描述】:

使用isInstanceOf 方法,可以检查对象的类型。例如:

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

如何显示所有类型的对象(如果可能的话?)?

【问题讨论】:

    标签: scala reflection types


    【解决方案1】:

    您可以在 2.10(M4 或更高版本)中轻松做到这一点:

    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
    

    这给了我们以下信息:

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

    在 2.10 之前的版本中,您将很难做类似的事情。

    【讨论】:

    • 谢谢,2.10 看起来确实很简单。你知道是否有可能在 pre-2.10 中列出所有类型?
    • Manifests 并不是真正为支持这种事情而设计的。您可以使用Java Reflection API 来获取超类、实现的接口等,但这与获取types 非常不同。
    【解决方案2】:

    这是另一个解决方案,它利用baseType 方法来具体化类型参数。

    import scala.reflect.runtime.universe._
    
    def typesOf[T : TypeTag](v: T): List[Type] =
      typeOf[T].baseClasses.map(typeOf[T].baseType)
    

    例子:

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

    【讨论】:

    • baseClasses 很方便,但当然,这些不是 types,这正是问题所要求的。还值得注意的是,这在 2.10 之前不起作用。
    • @TravisBrown 问题说 display 所有类型。 baseClasses 返回的是类型的 Symbol。您可以在所有这些上调用asTypeSymbol,当然也可以调用.asType.typeSignature
    • 但是例如说您想要List("1") 的类型,这样您就可以知道GenSeq[String] 是否是其中之一(无论出于何种原因不使用isInstanceOf)。一旦您使用了baseClasses,就无法获得该信息——您所能做的就是获得GenSeq 的类型符号。
    • 请注意,例如,typesOf(Seq(1)) contains typeOf[collection.TraversableLike[Int, Iterable[Int]]] 是错误的,尽管这绝对是它的一种类型。
    • @TravisBrown 我很确定它包含TraversableLike[Int, Seq[Int]]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多