2015-09-06 28 views
3

我想动态插入一个类型参数,即List[T],其中T只能在运行时找到。使用scala Type来设置类型参数(通过TypeTag?)

通常情况下,如果您已有现有类型参数T(不是这种情况),或者在运行期间使用TypeTag s,则可以创建类似于此的绑定。

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

我知道如何使用创建TypeTag,如果你有你的类型TtypeTag[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) 
       ^
+1

我不知道我明白了什么是'insertTag(标准杆)'预期的结果。你总是希望'fn'只有一个参数,还是可以有多个参数?那么预期的结果是什么? – Mifeet

+0

好问题,猜猜这些都是我一直试图简化的东西。实际上,我实际上为'fn.tupled'获取'TypeTag',它处理多个参数。 实际上,输出不是'List [T]',而是一个'akka.stream.scaladsl.Flow [T]',这与'List [T]'不同,这很有用(因此我必须添加' _',没有它就没有什么和错误)。 如果你放入一个实际的TypeTag(即insertTag(ru.typeTag [Integer])'),那么'insertTag'函数可以工作,但现在只需要一个'Type'就可以通过...... – Tycho

回答

1

我还没有想出如何转换TypeTypeTag。如果你的目标是让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> 
+0

哈,不错:)谢谢! – Tycho