如何TypeTag过程中保持类型参数的体现转换?(How to maintain type para

2019-10-29 17:48发布

从这个问题用了答案, 是否有可能一个TypeTag转换成清单? ,我可以转换TypeTag的体现。

不幸的是,使用这种方法,你就失去了类型参数。 由于事实,你正在使用的runtimeClass做转换。 下面是说明这一点的样本代码:

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._

// From: https://stackoverflow.com/questions/23383814/is-it-possible-to-convert-a-typetag-to-a-manifest
def getManifestFromTypeTag[T:TypeTag] = {
  val t = typeTag[T]
  implicit val cl = ClassTag[T](t.mirror.runtimeClass(t.tpe))
  manifest[T]
}

// Soon to be deprecated way
def getManifest[T](implicit mf: Manifest[T]) = mf

getManifestFromTypeTag[String] == getManifest[String]
//evaluates to true

getManifestFromTypeTag[Map[String, Int]] == getManifest[Map[String, Int]]
//evalutes to false. Due the erasure.

有没有办法从TypeTag转换的体现时,保留类型参数?

Answer 1:

ManifestFactory有一个名为classType所方法,它允许创建清单与类型参数。

下面是一个实现:

  def toManifest[T:TypeTag]: Manifest[T] = {
    val t = typeTag[T]
    val mirror = t.mirror
    def toManifestRec(t: Type): Manifest[_] = {
      val clazz = ClassTag[T](mirror.runtimeClass(t)).runtimeClass
      if (t.typeArgs.length == 1) {
        val arg = toManifestRec(t.typeArgs.head)
        ManifestFactory.classType(clazz, arg)
      } else if (t.typeArgs.length > 1) {
        val args = t.typeArgs.map(x => toManifestRec(x))
        ManifestFactory.classType(clazz, args.head, args.tail: _*)
      } else {
        ManifestFactory.classType(clazz)
      }
    }
    toManifestRec(t.tpe).asInstanceOf[Manifest[T]]
  }


文章来源: How to maintain type parameter during TypeTag to Manifest conversion?
标签: scala