根据scala doc,TypeTag包含的信息多于ClassTag。在我看来,TypeTag可以比ClassTag做更多的事情,比如将编译时的类型参数信息带到运行时等。
但是,以下示例显示ClassTag可以完成工作,而TypeTag则不能。我想了解原因。
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))
只有ClassTag会将模式匹配引导到None
(这是预期的行为),前两个注释行将提供Some
分支。
似乎ClassType可以在运行时反映对象的类型,而Type Tag则不能。但TypeTag不是ClassTag的超集吗?我想尽可能详细地了解解释。谢谢。
答案 0 :(得分:3)
此页面将为您提供帮助! 看一看:)
https://medium.com/@sinisalouc/overcoming-type-erasure-in-scala-8f2422070d20
添加更多细节,因为只有链接答案不合适......
ClassTag:有关值的运行时信息,但对于通用样式不好 TypeTag:有关类型
的运行时信息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)
}