问题
Our library uses TypeTags, but now we need to interact with another library which requires Manifests. Is there any simple way to create a Manifest from a TypeTag?
回答1:
gourlaysama's anwer uses Class[_], thus type arguments are being erased. I've come up with an implementation that preserves the type arguments here: How to maintain type parameter during TypeTag to Manifest conversion?
Here's the code:
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]]
}
回答2:
If you try naively to summon a Manifest
when a TypeTag
is present, the compiler will give you a hint as to the solution:
import reflect.runtime.universe._
import reflect.ClassTag
def test[A : TypeTag] = manifest[A]
error: to create a manifest here, it is necessary to interoperate with the type
tag `evidence$1` in scope.
however typetag -> manifest conversion requires a class tag for the corresponding
type to be present.
to proceed add a class tag to the type `A` (e.g. by introducing a context bound)
and recompile.
def test[A : TypeTag] = manifest[A]
^
So if you have a ClassTag
in scope, the compiler will be able to create the necessary Manifest
. You have two options:
Add a second context bound everywhere
TypeTag
is, as in:def test[A : TypeTag : ClassTag] = manifest[A] // this compiles
Or first convert the
TypeTag
to aClassTag
, then ask for aManifest
:def test[A](implicit ev: TypeTag[A]) = { // typeTag to classTag implicit val cl = ClassTag[A]( ev.mirror.runtimeClass( ev.tpe ) ) // with an implicit classTag in scope, you can get a manifest manifest[A] }
来源:https://stackoverflow.com/questions/23383814/is-it-possible-to-convert-a-typetag-to-a-manifest