使用scala Type设置类型参数(通过TypeTag?)

时间:2015-09-06 10:41:05

标签: scala generics reflection type-parameter

我想动态插入一个类型参数,即List[T],其中T只能在运行时找到。

通常,如果您已经有一个现有的类型参数T(不是这种情况),或者在运行时使用TypeTag s,您可以创建这样的绑定。

后者听起来像是要走的路,但这会将问题转移到“我如何在这里获取我的TypeTag”。

我知道如果你有类型TtypeTag[T]),或者如果你有一个类型为T的实例,那么如何创建一个TypeTag(参见getTypeTag下文)。

但是,我没有;我对我的类型所做的是reflect.runtime.universe.Type。可能会将其转换为TypeTag,以便我可以动态插入我的类型参数吗?

如果List也可以动态,也可以获得奖励积分。

scala> import scala.reflect.runtime.{universe => ru}

scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]

scala> def insertTag[T](tt: ru.TypeTag[T]) = List[T]_

scala> val fn = (a: String) => "foo"
fn: String => String = <function1>

scala> val pars = getTypeTag(fn).tpe.typeArgs.init(0)
pars: reflect.runtime.universe.Type = String

scala> insertTag(pars)
<console>:21: error: type mismatch;
 found   : reflect.runtime.universe.Type
 required: reflect.runtime.universe.TypeTag[?]
       insertTag(pars)
                 ^

1 个答案:

答案 0 :(得分:1)

我还没想出如何将Type转换为TypeTag。如果您的目标是仅为函数参数获取TypeTag,则可以修改函数getTypeTag以接受函数:

import scala.reflect.runtime.{universe => ru}
def getTypeTag[T: ru.TypeTag](obj: (T) => Any) = ru.typeTag[T]
def insertTag[T](tt: ru.TypeTag[T]) = List[T] _

val fn = (a: String, b: Int) => "foo"
var parTypeTag = getTypeTag(fn.tupled)
insertTag(parTypeTag) // Seq[(String, Int)] => List[(String, Int)] = <function1>