【问题标题】:Use Scala Quasiquotes to generate a class which inherits from a known class使用 Scala Quasiquotes 生成一个继承自已知类的类
【发布时间】:2015-11-30 23:07:46
【问题描述】:

这在代码中更容易解释。我想做类似的事情:

import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
val toolbox = currentMirror.mkToolBox()

val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
import universe._

class A { def a = "hello A" }

val c = toolbox.compile(q"""class C(x: Int) extends A { def r = x }""")

请注意动态生成的类 C 如何从已知/已编译的类 A 继承。

  1. 有没有办法使用知道A的工具箱?
  2. 如何使用动态生成的类?

【问题讨论】:

    标签: scala scala-quasiquotes


    【解决方案1】:

    这是一个例子。 “粘贴的”类由 REPL 的类加载器加载,因此您可以显式提供它。你也可以使用tb.eval

    $ scala
    Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> import reflect.runtime._,universe._,tools.reflect.ToolBox
    import reflect.runtime._
    import universe._
    import tools.reflect.ToolBox
    
    scala> :pa -raw
    // Entering paste mode (ctrl-D to finish)
    
    package p { class Parent(val i: Int) }
    
    // Exiting paste mode, now interpreting.
    
    
    scala> val tb = runtimeMirror($intp.classLoader).mkToolBox()
    tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@5e316c74
    
    scala> tb.compile(tb.parse("""case class Child(j: Int) extends p.Parent(42) ; val c = Child(17) ; c.j"""))()
    res0: Any = 17
    
    scala> val tb = currentMirror.mkToolBox()
    tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@59a67c3a
    
    scala> tb.compile(tb.parse("""case class Child(j: Int) extends p.Parent(42) ; val c = Child(17) ; c.j"""))()
    res1: Any = 17
    

    文档中的某处或此站点上肯定有一个示例。

    【讨论】:

    • 不错。是否可以在工具箱外使用Child?例如将它传递给正常 Scala 领域的方法。
    • 没有普通的Scalaland,只有多元宇宙。您可以从 tb.eval 返回任意值、ChildclassOf[Child] 等的实例。tb.define 为您提供一个顶级类的符号,您可以将其传递回工具箱(通常类是本地类)。 stackoverflow.com/q/12122939/1296806 类似stackoverflow.com/q/12122939/1296806
    • 显然此代码在 repl 之外不起作用,因为 $intp 是一个神奇的 repl-ony 值。有没有我可以编译的等价物?
    • 这只是为了表明镜像有一个定义的类加载器。 currentMirror 负责挑选类加载器。
    • 问题是我无法让它在 REPL 之外工作。使用 currentMirror 我得到“未找到:键入 Parent”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多