如何在运行时创建 Option 类型(反射)?

How can I create an Option type at runtime (reflection)?

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

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

为什么我想要这个:我有一个处理程序函数,它在一个类型上运行。在编译时我有这样的东西:

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 类型的 class,它有一个 Object[T] 甚至 Object[Thing] 类型的成员 maybeThing。假设在运行时我可以确定一个特定对象具有 T = BigThing,因此我想将 Option[BigThing] 而不是 Option[T] 或 Option[Thing] 传递给 handler()。这就是为什么我要尝试创建 Option[BigThing] 的运行时类型。

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

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

根据tutorial

there are three ways to instantiate a Type.

  • via method typeOf on scala.reflect.api.TypeTags, which is mixed into Universe (simplest and most common).
  • Standard Types, such as Int, Boolean, Any, or Unit are accessible through the available universe.
  • Manual instantiation using factory methods such as typeRef or polyType on scala.reflect.api.Types, (not recommended).

使用第三种方式,

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