scala - scala 的 ClassTag 和 TypeTag 的区别

标签 scala reflection

根据 Scala 文档, 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分支。
看来ClassTag可以在运行时反射(reflect)对象的类型,而 TypeTag不能。但不是TypeTag ClassTag的超集? 我想知道尽可能详细的解释。谢谢你。

最佳答案

这个页面会帮助你!
看一看 :)

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

添加更多详细信息,因为只有链接答案不合适...

ClassTag :关于值的运行时信息,但不适用于通用样式
TypeTag :关于类型的运行时信息

例如

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 - scala 的 ClassTag 和 TypeTag 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40202504/

相关文章:

ide - 在2010年初,有什么好的Scala IDE?

scala - Scala 中类型不相等的证据

java - 通用列表属性,获取通用类型

c# - BindingFlags.Default 等同于什么?

java - 运行包含在字符串中的一段代码

java - 在 Java 中实现 Scala PartialFunction 的最简单方法是什么?

Java SE 和 Scala 标准库 - 优选其中之一的情况

java - 通过反射 API 在类加载器之间传递参数

java - 是否可以在运行时从 java 对象中删除属性?

scala - 从 trait 获取一个类字段