我想动态插入一个类型参数,即List[T]
,其中T只能在运行时找到。
通常情况下,如果您已经有一个现有的类型参数T
(不是这种情况),或者在运行时使用TypeTag
s,您可以这样创建绑定。
后一种方法听起来是可行的,但这将问题转移到"我如何在这里获得我的TypeTag"。
我知道如何创建一个TypeTag使用,如果你有你的类型T
(typeTag[T]
),或者如果你有你的类型T
的实例(见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)
^
我还没有弄清楚如何将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>