【问题标题】:How can I create an Option type at runtime (reflection)?如何在运行时创建 Option 类型(反射)?
【发布时间】:2019-02-18 02:45:13
【问题描述】:

使用反射,我已经确定了一个事物的运行时类型,t:Type。现在我想创建一个新的 Option[t] 类型。我该怎么做?

val t: Type = ...
val optT: Type = ???  // Option of whatever t is

为什么我想要这个:我有一个对 Type 进行操作的处理函数。在编译时我有这样的东西:

trait Thing { name: String }
case class BigThing(name: String) extends Thing

case class Stuff[T <: Thing]( id: Int, maybeThing: Option[T] ) // contrived

def handler( t: Type ): Output = {...}

我可以反映,如果我有一个 Stuff 类型的类,它可能有一个 Object[T] 甚至 Object[Thing] 类型的成员。在运行时,假设我可以确定特定对象具有 T = BigThing,所以我想将 Option[BigThing],而不是 Option[T] 或 Option[Thing] 传递给 handler()。这就是我尝试创建 Option[BigThing] 的运行时类型的原因。

我确实尝试了以下方法,但 Scala 不喜欢它:

val newType = staticClass(s"Option[${runtimeTypeTAsString}]")

【问题讨论】:

  • t 来自哪里?
  • 所以给定t: Type 代表T 类型的值,你想要一个方法def makeOptionType(t: Type): Type 返回代表Option[T] 类型值的Type

标签: scala reflection scala-reflect


【解决方案1】:

根据tutorial

有三种方法可以实例化Type

  • 通过scala.reflect.api.TypeTags 上的typeOf 方法,该方法与Universe 混合(最简单且最常见)。
  • 可以通过可用的 Universe 访问标准类型,例如 IntBooleanAnyUnit
  • scala.reflect.api.Types 上使用typeRefpolyType 等工厂方法手动实例化,(不推荐)。

使用第三种方式,

import scala.reflect.runtime.universe._

class MyClass

val t: Type = typeOf[MyClass] //pckg.App.MyClass

val mirror = runtimeMirror(ClassLoader.getSystemClassLoader)

val optT: Type = mirror.universe.internal.typeRef(
  definitions.PredefModule.typeSignature, 
  definitions.OptionClass, 
  List(t)
) // Option[pckg.App.MyClass]

val optT1 : Type = typeOf[Option[MyClass]]

optT =:= optT1 // true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2022-11-29
    • 2019-10-22
    • 2011-03-07
    • 2012-01-13
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多