Scala程序是怎么被转换为JVM字节码?

12-02-25 banq
How to work with javap for Scala/Java interop - Stack Overflow

类 构造器和方法:

scala:

class X(i: Int) {
  def m1 = i*2
  def m2(a: Int)(b: Int) = a*b
  def m3(a: Int)(implicit b: Int) = a*b
}
<p>

被编译成一个文件名叫X.class:

X x = new X(7);
x.m1();
x.m2(3, 5);
x.m3(3, 5);
<p>

字段和值:

//Scala
val x = new X(5)
x.i = 3 // Setter
x.i // Getter

//Java
X x = new X(5);
x.i_$eq(3); // Setter
x.i(); // Getter
<p>

对象Objects,由于Java中没有Object概念,产生两个文件:X.class和X$.class, 第一个相当于接口,有静态方法,后者是单例不能被初始化,有一个字段hold住单例实例,取名为MODULE$

X.i();
X$.MODULE$.i();
<p>

Case class

Scala编译器将自动为其产生一个apply-method,为字段产生Getter方法,这样case class X(i:int)将在Java代码通过下面方式访问:

new X(3).i();
X$.MODULE$.apply(3);
<p>

Traits

trait T { def m } 将被编译到接口,放入T.class文件,然后通过Java类被访问:

class X implements T {
  public void m() {
    // do stuff here
  }
}
<p>

Functions

函数遍历将被编译成匿名实例,如Scala Object:

object X {
  val f: Int => Int = i => i*2
  def g: Int => Int = i => i*2
  def h: Int => Int => Int = a => b => a*b
  def i: Int => Int => Int = a => {
    def j: Int => Int = b => a*b
    j
  }
}
<p>

...见原文....

Java访问:

X.f().apply(7);
X.g().apply(7);
X.h().apply(3).apply(5);
X.i().apply(3).apply(5);
<p>
    

herdingdang
2012-02-26 08:31
以前看过groovy的编译器。感觉和这个差不多吧。总的流程是:

1. 它有个语法描述文件,是个自动机;

2. 用开源框架分析词法。

3. 生成抽象语法树。

4. 最后根据语法树,用visitor模式,遍历语法树,生成class code。

只是不知道为什么,groovy性能差scala好远。不过, groovy的web框架,grails,用起来倒是很方便,很喜欢。

猜你喜欢