编译Scala脚本。 Scala脚本的工作原理如何?

时间:2012-03-19 17:17:07

标签: scala groovy jvm-languages scalac scala-script

Groovy的

Groovy带有一个名为groovyc的编译器。对于每个脚本,groovyc生成一个扩展groovy.lang.Script的类,其中包含一个main方法,以便Java可以执行它。已编译类的名称与正在编译的脚本的名称相匹配。

例如,使用此HelloWorld.groovy脚本:

println "Hello World"

这就像这段代码:

class HelloWorld extends Script {
    public static void main(String[] args) {
        println "Hello World"
    }
}

Scala的

Scala附带了一个名为scalac的编译器。

例如,使用相同的HelloWorld.scala脚本:

println("Hello World")

代码对scalac无效,因为编译器需要类或对象定义,但在Scala REPL Interpreter中有效。怎么可能?在执行之前它是否包含在类中?

3 个答案:

答案 0 :(得分:5)

Scala-Script中的代码首先放在Scala对象中,然后编译为JVM-Bytecode,最后执行。您可以通过编写scala -Xprint:parser my_file.scala

来查看生成的Scala对象
package <empty> {
  object Main extends scala.ScalaObject {
    def <init>() = {
      super.<init>();
      ()
    };
    def main(argv: Array[String]): scala.Unit = {
      val args = argv;
      {
        final class $anon extends scala.AnyRef {
          def <init>() = {
            super.<init>();
            ()
          };
          println("hello world")
        };
        new $anon()
      }
    }
  }
}

答案 1 :(得分:2)

scalac会将您的代码编译为java字节码。 println("Hello World")本身不是有效的scala程序,因此scalac不会编译它。 你可以这样做:

object Test extends App {
  println("Hello World")
}

object Test {
  def main(args: Array[String]) {
    println("Hello World")
  }
}

然后,您可以使用scala Test运行输出。 在仅包含println("Hello World")行的文件上运行scala“解释器”将基本上将其包装在一个对象中(将其转换为我们上面看到的第一个表单),编译它并在引擎盖下为它运行它

请注意(即使代码看起来与java中的Hello World控制台应用程序非常相似),生成的编译程序与编译此java的结果相同

/*  note: this is Java code */
/* this does NOT compile to the same bytecode as the previous scala example*/
public class Test {
    public static void main (String args[]) {
        System.out.println ("Hello World");
    }
}

答案 2 :(得分:1)

使用scalac成功编译文件后,可以使用java类文件反汇编程序javap查看生成的类和方法签名(编辑:感谢@Luigi指出它是生成签名,而不是代码)。也就是说,scalac HelloWorld.scala后跟javap HelloWorld