2012-08-25 43 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]'?事实证明,我的工作很好。谢谢你的帮助,顺便说一句! –