【问题标题】:Difference between scala's ClassTag and TypeTagscala的ClassTag和TypeTag的区别
【发布时间】:2016-10-23 11:41:57
【问题描述】:

根据 scala doc,TypeTag 包含比ClassTag 更多的信息。在我看来TypeTagClassTag可以做更多的事情,比如把编译时的类型参数信息带到运行时等等。

但是,以下示例显示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 可以在运行时反映对象的类型,而TypeTag 不能。但是TypeTag不是ClassTag的超集吗?我想知道尽可能详细的解释。谢谢。

【问题讨论】:

标签: scala reflection


【解决方案1】:

此页面将为您提供帮助!
看看:)

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 类型是 Java 类的别名(例如 Long/String/etc.),ClassTag 还会返回底层 Java 类
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多