Wie benutzt Scala explizite Typen beim Auflösen von implicits?

8

Ich habe den folgenden Code, der spray-json verwendet, um JSON über die Methode parseJson in eine Fallklasse zu deserialisieren.

Je nachdem, wo das implizite JsonFormat [MyCaseClass] definiert ist (inline oder vom Companion-Objekt importiert) und ob bei der Definition ein expliziter Typ angegeben wurde, wird der Code möglicherweise nicht kompiliert.

Ich verstehe nicht, warum das Importieren des impliziten vom Companion-Objekt erfordert, dass es einen expliziten Typ hat, wenn es definiert ist, aber wenn ich es inline einfüge, ist das nicht der Fall?

Interessanterweise lokalisiert IntelliJ die impliziten Parameter (über cmd-shift-p) in allen Fällen korrekt.

Ich benutze Scala 2.11.7.

Fehlerhafter Code - Platzhalterimport vom begleitenden Objekt, abgeleiteter Typ:

%Vor%

Ergebnisse in:

%Vor%

Beachten Sie, dass das Gleiche bei einem expliziten Import von myCaseClassSchemaFormat implizit geschieht.

Arbeitscode # 1 - Platzhalterimport von Begleitobjekt, expliziter Typ:

Wenn Sie dem JsonFormat im Companion-Objekt einen expliziten Typ hinzufügen, wird der Code kompiliert:

%Vor%

Arbeitscode # 2 - Impliziert inline, abgeleiteter Typ:

Aber die impliziten Parameter in die Zeile zu setzen, wo sie verwendet werden, ohne der explizite Typ, funktioniert auch!

%Vor%     
MrProper 07.09.2015, 12:26
quelle

1 Antwort

3

Nach der Suche nach der Fehlermeldung, die Huw in seinem Kommentar erwähnt hat, konnte ich diese StackOverflow-Frage von 2010 finden: Warum erlaubt dieser explizite Aufruf einer Scala-Methode, dass sie implizit aufgelöst wird?

Dies führte mich zu dieser Scala-Ausgabe, die 2008 erstellt und 2011 geschlossen wurde: Ссылка (' expliziten Ergebnistyp für implizite Konvertierungen benötigen? ')

Martin sagte:

  

Ich habe eine etwas permissivere Regel implementiert: Eine implizite Konvertierung ohne expliziten Ergebnistyp ist nur in dem Text sichtbar, der seiner eigenen Definition folgt. Auf diese Weise vermeiden wir die zyklischen Referenzfehler. Ich schließe für jetzt, um zu sehen, wie das funktioniert. Wenn wir noch Probleme haben, kommen wir zurück.

Das trifft zu - wenn ich den breaking code neu anordne, so dass das begleitende Objekt zuerst deklariert wird, wird der Code kompiliert. (Es ist immer noch ein bisschen seltsam!)

(Ich vermute, dass ich die 'implizite Methode hier nicht finden kann' Nachricht, weil ich einen impliziten Wert anstelle einer Konvertierung habe - obwohl ich hier davon ausgehe, dass die Grundursache ist das gleiche wie oben).

    
MrProper 08.09.2015, 10:44
quelle

Tags und Links