简体   繁体   English

在Scala中,Universe.TypeTag,TypeRef和Type有什么区别?

[英]In Scala, What is the difference between universe.TypeTag, TypeRef, and Type?

There are 3 different classes all bounded to a universe: TypeTag , TypeRef , and Type . 有3种不同的类都绑定到Universe: TypeTagTypeRefType Why do we need all 3? 为什么我们需要全部三个? If I only have a Type , how do I convert it to a TypeTag or TypeRef ? 如果我只有Type ,如何将其转换为TypeTagTypeRef

Eg I have obtain a common super type through a Scala reflection API function: 例如,我已经通过Scala反射API函数获得了通用的超级类型:

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

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

How do I convert it into TypeTag or TypeRef ? 如何将其转换为TypeTagTypeRef

TypeRef is a specific case of Type : TypeRefType一种特殊情况:

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

You can check if a Type is actually a TypeRef by pattern-matching: 您可以通过模式匹配来检查Type是否实际上是TypeRef

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

TypeTag[A] is a way to get access to Type which 1) works for different mirrors; TypeTag[A]是一种访问Type的方法,其中1)适用于不同的镜像; 2) can be generated by the compiler automatically from the type parameter (note that Type is not generic). 2)可以由编译器从type参数自动生成(请注意Type不是通用的)。

To convert Type to TypeTag , from How to create a TypeTag manually? 要将Type转换为TypeTag ,从如何手动创建TypeTag? :

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]
    }
  })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM