Что действительно происходит за Scala runtime/REPL при запуске программы .scala?

Когда я запускаю из командной строки что-то вроде следующего: что на самом деле происходит?

> scala hello.scala

Есть ли hello.class, сгенерированный, выполненный, а затем отброшенный? Или Scala ведет себя как интерпретатор в этом случае? Я просто думаю, что, конечно, я не могу сделать то же самое для Java:

> java hello.java

Ответ 1

Да, есть hello.class. Компилятор будет обернуть ваш код внутри объекта Main, скомпилировать его, затем выполнить Main.main, учитывая hello.scala из

println(args.mkString)
println(argv.mkString)

Если вы запустите с опцией -Xprint:parser: scala -Xprint:parser hello.scala foo bar, вы увидите, как код будет перезаписан:

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(args.mkString);
          println(argv.mkString)
        };
        new $anon()
      }
    }
  }
}

Этот код затем скомпилирован (я верю в файловую систему с памятью, но я не уверен) и выполнен. Глядя на ScriptRunner, я вижу, что временный каталог создается в папке temp по умолчанию. Например, глядя на мою систему, я вижу кучу папок %TEMP%/scalascript*.

Обратите внимание, что даже в интерпретаторе код не интерпретируется. См. Scala: существует ли класс по умолчанию, если класс не определен? для получения дополнительной информации (он действительно перезаписывается, компилируется и оценивается).