在Scala中,universe.TypeTag,TypeRef和Type之间有什么区别?

时间:2016-06-04 23:48:17

标签: scala dynamic scala-reflect

有三个不同的类都与Universe绑定:TypeTagTypeRefType。为什么我们需要全部3个?如果我只有Type,如何将其转换为TypeTagTypeRef

E.g。我通过Scala反射API函数获得了一个通用的超类型:

val at = ...some TypeTag...
val bt = ...some TypeTag...

val tpe = ScalaReflection.universe.lub(List(at.tpe, bt.tpe))
ScalaReflection.universe.(tpe)

如何将其转换为TypeTagTypeRef

1 个答案:

答案 0 :(得分:0)

TypeRefType的具体案例:

abstract type TypeRef >: Null <: Universe.TypeRefApi with Universe.Type 

您可以通过模式匹配检查Type实际上是TypeRef

tpe match {
  case TypeRef(prefix, sym, args) =>
  // or alternately
  case typeRef: TypeRef =>
}

TypeTag[A]是一种访问Type的方法,其中1)适用于不同的镜像; 2)编译器可以自动从类型参数生成(注意Type不是通用的。)

Type转换为TypeTagHow to create a TypeTag manually?

import scala.reflect.runtime.universe._

def typeToTypeTag[T](
  tpe: Type,
  mirror: reflect.api.Mirror[reflect.runtime.universe.type]
): TypeTag[T] = {
  TypeTag(mirror, new reflect.api.TypeCreator {
    def apply[U <: reflect.api.Universe with Singleton](m: reflect.api.Mirror[U]) = {
      assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
      tpe.asInstanceOf[U#Type]
    }
  })
}