Компиляция скриптов Scala. Как работает скрипт Scala?
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. Как это возможно? Это обернуто в классе перед выполнением?
3 ответа
Код в 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()
}
}
}
}
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")
line в основном обернет его в объект (превратив его в первую форму, которую мы видели выше), скомпилирует и запустит для вас под капотом.
Обратите внимание, что (хотя код выглядит очень похоже на консольное приложение Hello World в Java), полученная скомпилированная программа - это не то же самое, что результат компиляции этой 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");
}
}
Как только вы успешно скомпилируете файл с scalac
, ты можешь использовать javap
дизассемблером файла класса java для просмотра сгенерированных сигнатур классов и методов (Edit: спасибо @Luigi за указание на то, что он генерирует сигнатуры, а не код). То есть, scalac HelloWorld.scala
с последующим javap HelloWorld
,