Difference between scala's ClassTag and TypeTag

reflection, scala

Solution

this page will help you! take a look :)

https://medium.com/@sinisalouc/overcoming-type-erasure-in-scala-8f2422070d20

add more detail, since only link answer is not appropriate...

ClassTag : runtime information about value, but not good with generic style TypeTag : runtime information about type

e.g.

object Test extends App {

  import scala.reflect.ClassTag
  def func[T : ClassTag](o: Any): Unit = {
    o match {
      case x: T => println(x)
      case _ => println(None)
    }
  }
  func[List[String]](List(1, 2, 3)) // List(1, 2, 3), not None!!! with List[String] type parameter... ClassTag only recognize List scale, not List[T]

  import scala.reflect.runtime.universe._
  def func2[T](o: T)(implicit tag: TypeTag[T]): Unit = {
    tag.tpe match {
      case TypeRef(utype, usymbol, args) => println(args.toString)
      case _ => println(None)
    }
  }
  func2(List(1, 2, 3)) // List(Int)
}

Problem

According to scala doc,`TypeTag` contains more information than `ClassTag`. It seems to me that `TypeTag` can do more things than `ClassTag`, like bring the type parameter information of compile time to runtime, etc. However, the following example shows that `ClassTag` can do the job, while the `TypeTag` not. I want to understand why. ``` import scala.reflect.ClassTag import scala.reflect.runtime.universe.TypeTag // def func[T](o: Any): Unit = { // def func[T : TypeTag](o: Any): Unit = { def func[T : ClassTag](o: Any): Unit = { o match { case x: T => println(Some(x)) case _ => println(None) }spark } func[Map[Int, Int]](List(1, 2, 3)) ``` Only `ClassTag` will lead the pattern matching to `None` (which is the expected behavior), the first two commented lines will come up with `Some` branch. It seems that `ClassTag` can reflect on object's type on runtime, while `TypeTag` can't. But isn't `TypeTag` a superset of `ClassTag`? I would like to know the explanation as detailed as possible. Thank you.

Original source

Related problems