2012-01-18 16 views
5

Perché in questo esempio non viene emesso alcun errore e b finisce con il valore predefinito?Inizializzazione valori scala

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

risposta

11

Quando si esegue questa operazione nel REPL, si sta effettivamente facendo:

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

b e sono assegnati a in ordine, quindi nel momento in cui si sta assegnando B, c'è un campo a, ma non è ancora stato assegnato a, quindi ha il valore predefinito di 0. In Java, non è possibile farlo perché non è possibile fare riferimento a un campo prima che sia definito. Credo che tu possa farlo in Scala per consentire un'inizializzazione pigra.

Si può vedere più chiaramente se si utilizza il seguente codice:

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 

Si possono avere i valori corretti assegnati se si fanno aa metodo:

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

o si può fare ba pigro val:

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

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

In questo caso, lo scalac non dovrebbe emettere un avviso? Dal momento che sembra essere un bug sicuro e probabilmente porterà a bug divertenti a volte. – Rogach

+0

@Rogach potrebbe essere un avvertimento nel compilatore Scala, suppongo, ma potrebbe essere utile, esp. per una valutazione pigra. Più nei regni di un controllo di stile come scalastyle (https://github.com/scalastyle/scalastyle) –

+0

@Rogach Rilevare tali situazioni in modo affidabile è difficile, se non impossibile. Scalac probabilmente avvertirà per casi semplici. –