Scala中var和val的内部实现是什么?有兴趣知道他们的实现的细节 - 是什么使var变为“var”如何实现可变结构与val(更像是最终的)结构,这使得它不可变。
答案 0 :(得分:12)
首先我创建Test.scala
:
class Test {
val x = 1
var y = 2
}
通过scalac Test.scala
进行编译以生成Test.class
,然后使用javap -p Test.class
获取
public class Test {
private final int x;
private int y;
public int x();
public int y();
public void y_$eq(int);
public Test();
}
因此,您可以看到val x
成为该类的private final
字段,还有一个public final
方法可以返回该值。
var y
成为一个非最终的私人领域,以及一个getter + setter对。 y_$eq(int)
是设定者。在scala中,那将是def y_=(newY: Int): Unit
。 Scala的语法糖会将y = someValue
转换为对y_=(someValue)
的调用。
答案 1 :(得分:4)
您必须区分声明(在类模板中)与定义(在块中,或在模板中声明成员并构成构造函数体)
4.2节中指定var
decl等同于getter / setter对。
作为实施细节,val
只是一个吸气剂。
两个成员都有一个私有支持字段,名称略有损坏:它有一个尾随空格。
有一些异常现象,例如:
scala> class X { final val x = 7 } // the underlying field is not initialized
defined class X
scala> :javap -prv X
{
[snip]
private final int x;
flags: ACC_PRIVATE, ACC_FINAL
[snip]
public $line5.$read$$iw$$iw$X();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: return
模板和块之间的材料差异:
scala> class Y { def y = { var z = 0; def z_=(zz: Int): Unit = ???; z = 1; z } }
scala> class Y { var z = 0; def z_=(zz: Int): Unit = ???; z = 1 }
<console>:7: error: method z_= is defined twice
在REPL中,你真的在制作模板(因为所有内容都包含在一个类中):
scala> var z = 0 ; def z_=(zz: Int): Unit = ???
<console>:7: error: method z_= is defined twice
conflicting symbols both originated in file '<console>'
var z = 0 ; def z_=(zz: Int): Unit = ???
^
scala> { var z = 0 ; def z_=(zz: Int): Unit = ??? }