如何在TypeTag转换为清单的过程中保持类型参数?

问题描述 投票:0回答:1

使用这个问题的答案,Is it possible to convert a TypeTag to a Manifest?,我可以将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转换为清单时,是否可以保留类型参数?

scala
1个回答
1
投票

ManifestFactory具有一个名为classType的方法,该方法允许使用类型参数创建Manifest。

这里是一个实现:

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]]
}
© www.soinside.com 2019 - 2024. All rights reserved.