【问题标题】:How to construct wildcard type in Scala macro?如何在 Scala 宏中构造通配符类型?
【发布时间】:2013-12-05 09:41:03
【问题描述】:

我不知道如何在 Scala 宏中以编程方式构造存在类型。

例如,假设我有一个ClassSymbol,它代表一个类C[T],它有一个类型参数。

现在,我如何以编程方式构造类型 C[_ <: java.lang.Number]

特别是,我不知道如何使用ExistentialType 构造函数对象。查看它的签名:

def apply(quantified: List[Symbol], underlying: Type): ExistentialType

quantified 传递什么?

【问题讨论】:

    标签: scala scala-macros existential-type


    【解决方案1】:

    据我了解,您需要自己创建量化符号,手动设置它们的签名。这是我编译typeOf[C[_ <: Number]] 时打印的-Ymacro-debug-lite 的删节和改编版本。也许 Jason 或 Paul 知道一种避免手动创建符号的快捷方式,但我不确定它是否存在于公共 API 中。

    class C[T]
    
    object Test extends App {
      import scala.reflect.runtime.universe._
      val c = typeOf[C[_]].typeSymbol
      val targ = build.newNestedSymbol(NoSymbol, newTypeName("_$1"), NoPosition, build.flagsFromBits(34359738384L), false)
      build.setTypeSignature(targ, TypeBounds(typeOf[Nothing], typeOf[Number]))
      println(ExistentialType(List(targ), TypeRef(c.owner.asClass.thisPrefix, c, List(TypeRef(NoPrefix, targ, Nil)))))
    }
    

    【讨论】:

    • 非常感谢。虽然我不确定它是否可以与 NoSymbol 作为所有者一起使用。我记得尝试过这样的事情并遇到了一些崩溃。
    • 为了让代码 sn-p 更清楚一点,标志实际上是DEFERRED | EXISTENTIAL。遗憾的是后者在公共 API 中不可用。
    • Jason 建议 typer.packSymbols(sym.typeParams, sym.tpe)(这需要强制转换才能到达存在类型量词的 c.callsiteTyper), and then if you need to modify the type bounds of the underscore, use setTypeSignature`。
    猜你喜欢
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2018-09-27
    • 2013-09-03
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多