如何以编程方式编译和 运行 Scala 代码
How to compile and run Scala code programmatically
我有以下代码,我想即时编译它并运行它。
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello, world!")
}
}
到目前为止,我已经尝试过类似下面的方法:
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object MainScala {
def main(args: Array[String]): Unit = {
val toolbox = currentMirror.mkToolBox()
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println("Hello, world!")
| }
|}
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
var c = binary.getClass
val m = c.getMethod("main", classOf[Array[String]])
val params = Array("Apple", "Banana", "Orange")
m.invoke(null, null)
}
}
在 toolbox.compile(tree)
之后,我无法获得编译代码的 Class
对象。
如果您查看 binary
的类型,您会发现它是 () => Any
。因此,当您询问 .getClass
时,您实际上得到了 Function1
的子类,它没有 .main
.
工具箱不应该这样使用。
https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/reflect/ToolBox.scala#L120-L129
尝试
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println("Hello, world!")
| }
|}
|
|HelloWorld.main(Array())
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary() // Hello, world!
或
val params = """Array("Apple", "Banana", "Orange")"""
val source =
s"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println(args.toList)
| }
|}
|
|HelloWorld.main($params)
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary() // List(Apple, Banana, Orange)
或
import scala.reflect.runtime.universe._
val params = q"""Array("Apple", "Banana", "Orange")"""
val tree =
q"""
object HelloWorld {
def main(args: Array[String]): Unit = {
println(args.toList)
}
}
HelloWorld.main($params)
"""
val binary = toolbox.compile(tree)
binary() // List(Apple, Banana, Orange)
或
val params = """Array("Apple", "Banana", "Orange")"""
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println(args.toList)
| }
|}
|""".stripMargin
val tree = toolbox.parse(source)
val symbol = toolbox.define(tree.asInstanceOf[ImplDef])
val params1 = toolbox.parse(params)
val tree1 = q"$symbol.main($params1)"
val binary = toolbox.compile(tree1)
binary() // List(Apple, Banana, Orange)
我有以下代码,我想即时编译它并运行它。
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello, world!")
}
}
到目前为止,我已经尝试过类似下面的方法:
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object MainScala {
def main(args: Array[String]): Unit = {
val toolbox = currentMirror.mkToolBox()
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println("Hello, world!")
| }
|}
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
var c = binary.getClass
val m = c.getMethod("main", classOf[Array[String]])
val params = Array("Apple", "Banana", "Orange")
m.invoke(null, null)
}
}
在 toolbox.compile(tree)
之后,我无法获得编译代码的 Class
对象。
如果您查看 binary
的类型,您会发现它是 () => Any
。因此,当您询问 .getClass
时,您实际上得到了 Function1
的子类,它没有 .main
.
工具箱不应该这样使用。
https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/reflect/ToolBox.scala#L120-L129
尝试
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println("Hello, world!")
| }
|}
|
|HelloWorld.main(Array())
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary() // Hello, world!
或
val params = """Array("Apple", "Banana", "Orange")"""
val source =
s"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println(args.toList)
| }
|}
|
|HelloWorld.main($params)
|""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary() // List(Apple, Banana, Orange)
或
import scala.reflect.runtime.universe._
val params = q"""Array("Apple", "Banana", "Orange")"""
val tree =
q"""
object HelloWorld {
def main(args: Array[String]): Unit = {
println(args.toList)
}
}
HelloWorld.main($params)
"""
val binary = toolbox.compile(tree)
binary() // List(Apple, Banana, Orange)
或
val params = """Array("Apple", "Banana", "Orange")"""
val source =
"""
|object HelloWorld {
| def main(args: Array[String]): Unit = {
| println(args.toList)
| }
|}
|""".stripMargin
val tree = toolbox.parse(source)
val symbol = toolbox.define(tree.asInstanceOf[ImplDef])
val params1 = toolbox.parse(params)
val tree1 = q"$symbol.main($params1)"
val binary = toolbox.compile(tree1)
binary() // List(Apple, Banana, Orange)