【问题标题】:Use scala Type to set type parameter (thru TypeTag?)使用 scala Type 设置类型参数(通过 TypeTag?)
【发布时间】:2015-12-02 01:33:30
【问题描述】:

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

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

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

如果您有您的类型T (typeTag[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)
                 ^

【问题讨论】:

  • 我不确定我是否理解insertTag(pars) 的预期结果。您总是期望fn 有一个参数,还是可以有多个参数?那么预期的结果是什么?
  • 好问题,猜猜这些是我一直试图简化的部分。实际上,我实际上得到了fn.tupledTypeTag,它处理多个参数。实际上,输出不是List[T],而是akka.stream.scaladsl.Flow[T],与List[T] 不同,它很有用(因此我必须添加_,没有它就什么都没有和错误)。如果你输入一个实际的TypeTag(即insertTag(ru.typeTag[Integer])),那么insertTag 函数就可以工作,尽管现在让它只与Type 一起工作......

标签: scala generics reflection type-parameter


【解决方案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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 2012-08-19
    相关资源
    最近更新 更多