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

时间:2019-02-17 15:17:47

标签: scala reflection scala-reflect

使用反射,我确定了事物的运行时类型,即t:类型。现在,我想创建一个新的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}]")

1 个答案:

答案 0 :(得分:1)

根据tutorial

  

有三种实例化Type的方式。

     
      
  • 通过typeOf上的方法scala.reflect.api.TypeTags,它混合到Universe中(最简单,最常见)。
  •   
  • 可以通过可用的Universe访问诸如IntBooleanAnyUnit之类的标准类型。
  •   
  • 使用工厂方法(例如typeRef上的polyTypescala.reflect.api.Types进行手动实例化(不推荐)。
  •   

使用第三种方式,

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