问题描述
根据scala doc,TypeTag
比ClassTag
包含更多的信息.在我看来,TypeTag
比 ClassTag
可以做更多的事情,比如把编译时的类型参数信息带到运行时等等.
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.
但是,下面的示例表明 ClassTag
可以完成这项工作,而 TypeTag
则不然.我想了解原因.
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))
只有 ClassTag
会导致模式匹配为 None
(这是预期的行为),前两行注释会出现 Some
分支.
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.
似乎ClassTag
可以在运行时反映对象的类型,而TypeTag
不能.但是TypeTag
不是ClassTag
的超集吗?我想知道详细的解释.谢谢.
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.
推荐答案
此页面将为您提供帮助!
看看:)
this page will help you!
take a look :)
https://medium.com/@sinisalouc/overcoming-scala-8f2422070d20 中的类型擦除
添加更多细节,因为只有链接答案不合适...
ClassTag:关于值的运行时信息,但不适用于通用样式
TypeTag :关于类型的运行时信息
ClassTag : runtime information about value, but not good with generic style
TypeTag : runtime information about type
例如
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)
}
这篇关于scala 的 ClassTag 和 TypeTag 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!