2012-11-24 9 views
5

das Merkmal Given (vereinfacht)Scala :: Lazy Wert ist Null, es sei denn gedruckt?

trait A { 
    val eventStream: EventStream 
    val credentialsStorage = // something here 
    val userStorage = // something here 
    val crypto = // something here 
    ...  
    lazy val authSvc = new CoreAuthentication(credentialsStorage, new AuthenticationProviderResolver, userStorage, eventStream, crypto) 
} 

class T extends A with TraitProvidingEventStream with FlatSpec with [lot of another traits here] { 

    val eventStream = systemFromTraitProvidingEventStream.eventStream 

    "This" should "work" in { 
    println(authSvc) // this is "magic" 
    val user = authSvc.doSomethingWithUser(...); 
    } 
} 

wenn ich Linie als markiert entfernen // Das ist „Magie“, dann werde ich Nullpointer in der nächsten Zeile erhalten, so authSvc null ist.

Was kann da falsch sein?

Ich war nicht in der Lage sein, sauber kleinen Testfall dafür zu schaffen, in der Regel das funktioniert gut

+1

Sind Sie sicher, dass der Zugriff auf 'authSvc' eine NPE auslöst und nicht die Methode' doSomethingWithUser' oder ihre Parameter? – sschaef

+0

absolut, auch wenn es NPE irgendwo in doSomethingWithUser werfen würde - dann hat println nichts zu tun. – jdevelop

+0

Ich möchte dies debuggen, aber nicht sicher, wie. Jede Hilfe wird geschätzt. – jdevelop

Antwort

4

Diese einmal auf dem ML kam: Wenn eine Ausnahme ausgelöst wird, wenn eine faule val Initialisierung ist die val null ; aber Sie können versuchen, erneut zu init und es kann magisch arbeiten. (Das heißt, das "initialisierte" Bit-Flag für das Lazy-Val wird bei dem ersten fehlgeschlagenen Initialisierungsversuch nicht gesetzt.)

Ich denke, der Fall auf der ML hatte mit Init-Reihenfolge von Vals in Merkmalen zu tun, also vielleicht das ist dein Problem. Es ist infamously gefährlich, sich darauf zu verlassen, daher der Rat, Defs in Traits zu verwenden. Siehe Luigis Kommentar zu DelayedInit.

Verwandte Themen