2016-05-04 11 views
5

Ich habe diese Art von Zeile verwendet, um meine Implikationen zu testen, indem ich sie durch Copy-Paste-Unfällen implizit mache. Es dauerte einige Zeit, um herauszufinden, warum dies kompiliert trotz mir nicht erwartet, dass es zu kompilieren:scala implizit sich vervollständigen?

> console 
[info] Starting scala interpreter... 
[info] 
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66). 
... skipped some comment lines ... 

scala> case object Foo 
defined object Foo 

scala> object Bar { implicit val f: Foo.type = implicitly[Foo.type] } 
defined object Bar 

scala> val x = Bar.f 
x: Foo.type = null 

scala> 

Ich würde Bar erwarten Kompilation zum Scheitern verurteilt, weil es keine implizite val vom Typ Foo.type (der Fall Objekt NICHT implizit deklariert).

Für mich sieht es so aus, als ob der Compiler fs eigene Deklaration (linke Seite) benutzt, um seine Implementierung abzuschließen (rechte Seite).

Ist das wirklich das beabsichtigte Verhalten? Zur Laufzeit führt dies zu einem unerwarteten Verhalten mit null Werten (meistens NPEs für mich).

Antwort

3

Dies geschieht, weil f als implicit deklariert ist. Also in gewisser Weise löst sich die rechte Seite von implicit val f: Foo.type = implicitly[Foo.type] in das implizite val f selbst auf!

Wenn Sie die implicit aus dieser Zeile entfernen, würde die Kompilierung fehlschlagen. Was ich frage mich ist, warum verwenden Sie so eine Linie obwohl.

Das ist definitiv ein Problem für mich. Jemand sieht aus wie letztes Jahr schon eine Notiz.

Enhancement Request

+0

Das genannte Problem wird als "Erweiterung" bezeichnet. Ich würde dies als einen Fehler betrachten. Jede Chance, ihre Bedeutung zu erhöhen? – sthielo

+0

Ich stimme zu, es ist ein Problem. Ich denke, Sie können weitermachen und ein Problem mit ihnen protokollieren. Oder vielleicht fügen Sie einen Kommentar zu dieser "Erweiterung" Anfrage hinzu. Ich würde das auch tun. –

+3

Wenn es ein Fehler ist, ist es in der Spezifikation, nicht der Code. Die val-Definition gehört implizit zum äußeren Bereich, so dass sie als Kandidat für die Suche gilt. Eine übliche Problemumgehung besteht darin, den Zielwert nicht mit Anmerkungen zu versehen, da implizite Val f = implizit [Foo.type] 'funktionieren würde, da Compiler nicht wissen, dass" f "vom gewünschten Typ ist. – knutwalker

Verwandte Themen