Используйте Scala Quasiquotes для генерации класса, который наследуется от известного класса
Это легче объяснить в коде. Я хочу сделать что-то вроде:
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
это известно / уже скомпилировано.
- Есть ли способ использовать набор инструментов, который знает о
A
? - Как использовать динамически сгенерированный класс?
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
Конечно, есть примеры в документации где-то или на этом сайте.