使用ClassTag和TypeTag获取Seq [AnyRef]元素的类型

时间:2017-07-06 22:46:41

标签: scala

通过以下测试用例,我将检查Seq[AnyRef]

的元素类型
  @Test
  def testClassTagAndTypeTag(): Unit = {
    import scala.reflect.runtime.universe._
    def getTypeTag[T: TypeTag](data: T): TypeTag[T] = typeTag[T]
    def getClassTag[T: ClassTag](data: T): ClassTag[T] = implicitly[ClassTag[T]]
    val data = Seq(List(1), "Hello", new Box(1))
    data.foreach(x => {
      println(s"TypeTag: ${getTypeTag(x)}, tpe: ${getTypeTag(x).tpe}")
    })
    data.foreach(x => {
      println(s"ClassTag: ${getClassTag(x)}")
    })
  }

上述代码的输出是:

TypeTag: TypeTag[java.lang.Object], tpe: java.lang.Object
TypeTag: TypeTag[java.lang.Object], tpe: java.lang.Object
TypeTag: TypeTag[java.lang.Object], tpe: java.lang.Object
ClassTag: Object
ClassTag: Object
ClassTag: Object

我认为type标签应输出真实类型的Seq元素,这应该是

List[Int]
String
Box[Int]

1 个答案:

答案 0 :(得分:2)

当你有Seq[AnyRef]时,为时已晚。 xdata.foreach(x => ...)的类型仅为AnyRef,因此getTypeTag(x)getClassTag(x)会给出相应的结果。

相反,您可以将类型标记与值一起存储,例如

case class WithTypeTag[A](x: A)(implicit val tag: TypeTag[A])

val data = Seq(WithTypeTag(List(1)), WithTypeTag("Hello"), WithTypeTag(new Box(1)))
data.foreach(x => println(x.tag))