2012-08-25 68 views

回答

52

W.r.t彙編工具箱只能運行表達式=返回值,但不能得到的類或文件/字節數組與編譯結果。

但是它仍然可能實現你想要什麼,因爲在斯卡拉它很容易使用隱式值從類型層面去值水平:

編輯。在2.10.0-RC1中,ToolBox的一些方法已被重命名。 parseExpr現在只是parse,runExpr現在被稱爲eval

scala> import scala.reflect.runtime._ // requires scala-reflect.jar 
             // in REPL it's implicitly added 
             // to the classpath 
             // but in your programs 
             // you need to do this on your own 
import scala.reflect.runtime 

scala> val cm = universe.runtimeMirror(getClass.getClassLoader) 
cm @ 41d0fe80: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.nsc.interpreter.IMain$TranslatingClassLoader... 

scala> import scala.tools.reflect.ToolBox // requires scala-compiler.jar 
              // in REPL it's implicitly added 
              // to the classpath 
              // but in your programs 
              // you need to do this on your own 
import scala.tools.reflect.ToolBox 

scala> val tb = cm.mkToolBox() 
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

scala> tb.runExpr(tb.parseExpr("class C; scala.reflect.classTag[C].runtimeClass")) 
res2: Any = class __wrapper$1$f9d572ca0d884bca9333e251c64e980d$C$1 

更新#1。如果您不需要java.lang.Class,只需要實例化編譯後的類,則可以直接在提交到runExpr的字符串中編寫new C

更新#2。也可以讓runExpr使用從變量名到運行時值的自定義映射。例如:

scala> val build = scala.reflect.runtime.universe.build 
build: reflect.runtime.universe.BuildApi = [email protected] 

scala> val x = build.setTypeSignature(build.newFreeTerm("x", 2), typeOf[Int]) 
x: reflect.runtime.universe.FreeTermSymbol = free term x 

scala> tb.runExpr(Apply(Select(Ident(x), newTermName("$plus")), List(Literal(Constant(2))))) 
res0: Any = 4 

在這個例子中我創建具有爲2的值的自由項(該值不必是一個原始的 - 它可以是自定義的對象)以及標識符綁定到它。然後將此值原樣用於由工具箱編譯和運行的代碼。

的例子使用手冊AST組裝,但它是可以編寫解析字符串,發現了綁定標識,查找他們值某種映射函數,然後創建相應的免費條款。雖然在Scala 2.10.0中沒有這樣的功能。

+0

謝謝!一個後續:有沒有辦法讓我用Scala的反射來處理這個返回的'java.lang.Class',或者我只需要堅持原來的Java呢? –

+2

當然。使用' .classSymbol()',其中 ='scala.reflect.runtime.universe.runtimeMirror(.getClassLoader )'。然後你會得到一個Scala反射符號,可以使用Scala反射API進行檢查。 –

+0

爲什麼您使用的''而不是universe.runtimeMirror(getClass.getClassLoader)'reflect.runtime.currentMirror'和'scala.reflect.classTag [C] .runtimeClass',而不是'classOf [C]'?事實證明,我的工作很好。謝謝你的幫助,順便說一句! –