0

时髦的

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 带有一个名为scalac.

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

println("Hello World")

该代码对 无效scalac,因为编译器需要类或对象定义,但可以在 Scala REPL 解释器中使用。怎么可能?它在执行之前是否包含在一个类中?

4

3 回答 3

6

Scala-Script 中的代码首先放置在 Scala 对象中,然后编译为 JVM-Bytecode 并最后执行。您可以通过以下方式查看生成的 Scala 对象scala -Xprint:parser my_file.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()
      }
    }
  }
}
于 2012-03-19T17:42:34.633 回答
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。在仅包含该行的文件上运行 scala“解释器”println("Hello World")基本上会将其包装在一个对象中(将其转换为我们在上面看到的第一种形式),编译它并在引擎盖下为您运行它。

请注意(即使代码看起来非常类似于 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");
    }
}
于 2012-03-19T17:39:15.447 回答
1

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

于 2012-03-19T17:39:19.677 回答