在運行 scala 腳本期間,我希望它生成一些代碼并執行它。
我以為我在網上找到了兩個可能有用的例子,但沒有成功
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
import java.io.{File, FileWriter}
def runstuff() = {
val fileWriter = new FileWriter(new File("temporaryScalaFile.scala"))
fileWriter.write("println(\"hello\")")
fileWriter.close()
temporaryScalaFile.scala
val cm = scala.reflect.runtime.universe.runtimeMirror(getClass.getClassLoader)
val tb = cm.mkToolBox()
val str = tb.eval(tb.parse("new String(\"Yo\")"))
println(str)
}
這些可能是過時的例子。
有沒有人有一個作業或修復?
uj5u.com熱心網友回復:
我將在如何在 Scala3 中運行時編譯和執行 Scala 代碼?
- 比如你可以用李浩毅的菊石
ammonite.Main(verboseOutput = false).runCode("""println("Hello, World!")""")
// Hello, World!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = "com.lihaoyi" % "ammonite" % "2.5.4" cross CrossVersion.full
- 您也可以使用標準的 Scala 2 REPL解釋器
scala.tools.nsc.interpreter.shell.Scripted()
.eval("""System.out.println("Hello, World!")""")
// Hello, World!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value % "scala-compiler" % scalaVersion.value
- 您可以使用 Scala 2 反射工具箱
import scala.tools.reflect.ToolBox // implicit
val tb = scala.reflect.runtime.currentMirror.mkToolBox()
tb.eval(tb.parse("""println("Hello, world!")"""))
// Hello, world!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value % "scala-compiler" % scalaVersion.value
- 如果你有一個
scala.reflect.runtime.universe.Treeq"..."而不是純字串,那么你不需要決議
import scala.reflect.runtime.universe.Quasiquote // implicit for q"..." interpolator
import scala.tools.reflect.ToolBox // implicit for .eval
scala.reflect.runtime.currentMirror.mkToolBox()
.eval(q"""println("Hello, World!")""") // Hello, World!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value % "scala-compiler" % scalaVersion.value
- 如果您有一個
scala.reflect.runtime.universe.Exprreify {...}(樹上的靜態型別包裝器)而不是純字串,那么您也不需要決議
import scala.reflect.runtime.universe.reify
import scala.tools.reflect.ToolBox
scala.reflect.runtime.currentMirror.mkToolBox()
.eval(reify{ println("Hello, World!") }.tree)
// Hello, World!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value % "scala-compiler" % scalaVersion.value
- 以上都是在 Scala 2 中運行 Scala 2 代碼。如果我們想在 Scala 2 中運行 Scala 3 代碼,那么我們可以使用標準的 Scala 3 REPL解釋器
(new dotty.tools.repl.ScriptEngine).eval("""println("Hello, World!")""")
// Hello, World!
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value %% "scala3-compiler" % "3.1.3" cross CrossVersion.for2_13Use3
scalacOptions = "-Ytasty-reader"
- 您也可以使用JSR223腳本。根據您是否擁有
scala-compiler或scala3-compiler在您的類路徑中,您將運行 Scala 2 或 Scala 3(上述兩個腳本引擎之一:Scala 2scala.tools.nsc.interpreter.shell.Scripted或 Scala 3dotty.tools.repl.ScriptEngine)。如果您首先添加了兩個依賴項,則獲勝。
new javax.script.ScriptEngineManager(getClass.getClassLoader)
.getEngineByName("scala")
.eval("""println("Hello, World!")""")
// Hello, World!
如果您想更好地控制使用的依賴項(無需重新匯入專案),您可以使用 Coursier 并指定類加載器
import coursier._ // libraryDependencies = "io.get-coursier" %% "coursier" % "2.1.0-M6-53-gb4f448130"
val files = Fetch()
.addDependencies(
Dependency(Module(Organization("org.scala-lang"), ModuleName("scala-compiler")), "2.13.9"),
// Dependency(Module(Organization("org.scala-lang"), ModuleName("scala3-compiler_3")), "3.2.0"),
)
.run()
val classLoader = new java.net.URLClassLoader(
files.map(_.toURI.toURL).toArray,
/*getClass.getClassLoader*/null // ignoring current classpath
)
new javax.script.ScriptEngineManager(classLoader)
.getEngineByName("scala")
.eval("""
type T = List[Option[A]] forSome {type A} // Scala 2
//type T = [A] =>> [B] =>> (A, B) // Scala 3
System.out.println("Hello, World!")
""")
// Hello, World!
- 您可以使用實際的編譯器自己在 Scala 2 中實作 Eval
import scala.reflect.internal.util.{AbstractFileClassLoader, BatchSourceFile}
import scala.reflect.io.{AbstractFile, VirtualDirectory}
import scala.reflect.runtime.universe
import scala.reflect.runtime
import scala.reflect.runtime.universe.{Mirror, TermName}
import scala.tools.nsc.{Global, Settings}
val code =
s"""
|package mypackage
|
|object Main {
| def main(args: Array[String]): Unit = {
| println("Hello, World!")
| }
|}""".stripMargin
val directory = new VirtualDirectory("(memory)", None)
val runtimeMirror = createRuntimeMirror(directory, runtime.currentMirror)
compileCode(code, List(), directory)
runObjectMethod("mypackage.Main", runtimeMirror, "main", Array.empty[String])
// Hello, World!
def compileCode(
code: String,
classpathDirectories: List[AbstractFile],
outputDirectory: AbstractFile
): Unit = {
val settings = new Settings
classpathDirectories.foreach(dir => settings.classpath.prepend(dir.toString))
settings.outputDirs.setSingleOutput(outputDirectory)
settings.usejavacp.value = true
val global = new Global(settings)
val run = new global.Run
run.compileSources(List(new BatchSourceFile("(inline)", code)))
// val unit = run.units.next()
// println("source=" unit.source.content.mkString)
// println("typed tree=" unit.body)
}
def runObjectMethod(
objectName: String,
runtimeMirror: Mirror,
methodName: String,
arguments: Any*
): Any = {
val objectSymbol = runtimeMirror.staticModule(objectName)
val objectModuleMirror = runtimeMirror.reflectModule(objectSymbol)
val objectInstance = objectModuleMirror.instance
val objectType = objectSymbol.typeSignature
val methodSymbol = objectType.decl(TermName(methodName)).asMethod
val objectInstanceMirror = runtimeMirror.reflect(objectInstance)
val methodMirror = objectInstanceMirror.reflectMethod(methodSymbol)
methodMirror(arguments: _*)
}
def createRuntimeMirror(directory: AbstractFile, parentMirror: Mirror): Mirror = {
val classLoader = new AbstractFileClassLoader(directory, parentMirror.classLoader)
universe.runtimeMirror(classLoader)
}
構建.sbt
scalaVersion := "2.13.8"
libraryDependencies = scalaOrganization.value % "scala-compiler" % scalaVersion.value
Scala反射:用protobuf編譯akka actor
在運行時動態編譯多個 Scala 類
如何評估使用 InterfaceStability 注釋的代碼(因“涉及類 InterfaceStability 的非法回圈參考而失敗”)?
Scala反射中的Tensorflow
Scala Presentation Compiler - 最小示例
什么是“Scala 演示文稿編譯器”?
Scala中的“評估”
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/512170.html
上一篇:Scala-根據行數拆分資料幀
