2012-01-18 14 views
5

なぜこの例では、エラーはスローされず、bはデフォルト値を保持しますか?あなたはREPLでこれを行うとスカラ値の初期化

scala> val b = a; val a = 5 
b: Int = 0 
a: Int = 5 

答えて

11

、あなたが効果的に行っている:あなたはBを代入している時に、そこにあるので

class Foobar { val b = a; val a = 5 } 

BとAは、順番にに割り当てられていますフィールドaにはまだ割り当てられていないので、デフォルト値は0です。Javaでは、定義される前にフィールドを参照できないため、これを行うことはできません。私は怠惰な初期化を可能にするためにScalaでこれを行うことができると信じています。

あなたがより明確に次のコードを使用している場合、これを見ることができます:

scala> class Foobar { 
    println("a=" + a) 
    val b = a 
    println("a=" + a) 
    val a = 5 
    println("a=" + a) 
} 
defined class Foobar 

scala> new Foobar().b 
a=0 
a=0 
a=5 
res6: Int = 0 

あなたがAAメソッド作る場合は、割り当てられた正しい値を持つことができます。

class Foobar { val b = a; def a = 5 } 
defined class Foobar 
scala> new Foobar().b 
res2: Int = 5 

をしたり、BAは怠惰なことができますval:

scala> class Foobar { lazy val b = a; val a = 5 } 
defined class Foobar 

scala> new Foobar().b 
res5: Int = 5 
+2

このような状況では、スケーラックで警告を発するべきではありませんか?それは確かなバグであると思われるので、時々面白いバグにつながるかもしれません。 – Rogach

+0

@Rogachそれは、私が想定しているScalaコンパイラでは警告になる可能性がありますが、役に立つかもしれません。怠惰な評価のために。 scalastyle(https://github.com/scalastyle/scalastyle)のようなスタイルチェッカーの分野では、より多く –

+0

@Rogachこのような状況を確実に検出することは、不可能ではないにしても、困難です。 Scalacはおそらく単純なケースに対して警告を発するでしょう。 –