简体   繁体   中英

Use ClassTag and TypeTag to get type of the elements of Seq[AnyRef]

With the following test case, I would check the type of the elements of a 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)}")
    })
  }

The output of the above code is:

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

I thought that the type tag should output the real type of Seq's elements, which should be

List[Int]
String
Box[Int]

By the time you have a Seq[AnyRef] , it's too late. The type of x in data.foreach(x => ...) is just AnyRef , so getTypeTag(x) and getClassTag(x) give corresponding results.

Instead, you can store type tag together with value, eg

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM