Scala räumt der impliziten Konvertierung Vorrang vor "natürlichen" Operationen ein ... Warum? Ist das ein Fehler? Oder mache ich etwas falsch?

8

Dieser einfache Test funktioniert natürlich wie erwartet:

%Vor%

Jetzt bringe ich das in den Geltungsbereich:

%Vor%

Ich definiere eine neue Klasse und eine + = Operation darauf und eine praktische implizite Konvertierung für die Zeiten, wenn ich Int einen Int-Wert von A hinzufügen möchte.

Ich hätte nie erwartet, dass dies die Art und Weise beeinflussen würde, wie sich meine regulären Int-Operationen verhalten, wenn die Klasse "A" überhaupt nicht Teil des Ausdrucks ist.

Aber es tut:

%Vor%

Was hier zu geschehen scheint, ist, dass das b: Int implizit in ein "A" umgewandelt wird, das nicht an eine Variable gebunden ist, und dann wird + = aufgerufen, um die Ergebnisse zu verwerfen.

Scala scheint der impliziten Umwandlung gegenüber dem natürlichen + = - Verhalten (Compiler-Magie, nicht eine tatsächliche Methode), die bereits für Ints definiert wurde, Vorrang einzuräumen. Common-sense sowie ein C ++ - Hintergrund sagt mir, dass implicits nur als letzter Ausweg aufgerufen werden sollte, wenn die Kompilierung sonst fehlschlagen würde. Das führt zu mehreren Fragen ...

  • Warum? Ist das ein Fehler? Ist es Absicht?
  • Gibt es einen Workaround (außer nicht "+=" für meine DSL "+=" Operation)?

Danke

    
Alex R 21.04.2010, 13:00
quelle

5 Antworten

1

Selbst wenn man der Erklärung von Eastsun widersteht, scheint es sich um einen Fehler zu handeln, und es sollte die b=b+1 Transformation versuchen, bevor eine implizite Konvertierung für += versucht wird.

Bitte stellen Sie diese Frage der scala-user Email-Liste per Email an [email protected] oder besuchen Sie n4.nabble.com/Scala-User-f1934582.html. Wenn es ein Fehler ist, wird es dort bemerkt und behoben.

    
Ken Bloom 21.04.2010, 13:35
quelle
13

Wie andere bemerkt haben, kann Int keine +="Methode" haben, weil Int unveränderlich ist. Was stattdessen passiert, ist, dass x + = 1 als Kurzform für x = x + 1 behandelt wird, aber nur wenn es keine gibt Methode namens + =, die für den Typ definiert ist. Daher hat die Methodenauflösung Vorrang.

In Anbetracht der Tatsache, dass Sie in Scala + = Methoden definieren können und Sie auch + = auf Variablen anwenden können, hätten wir die Priorität der beiden ändern können? I.e. Versuchen Sie, expanded + = first und nur wenn dies fehlschlägt, suchen Sie nach einer Methode namens + =?

Theoretisch ja, aber ich behaupte, es wäre schlimmer gewesen als das derzeitige Schema. Praktisch, nein. Es gibt viele Arten in der Sammlungsbibliothek von Scala, die beide eine + -Methode für definieren nicht-destruktive Addition und a + = Methode für die destruktive Addition. Wenn wir die Priorität umgestellt hätten, dann ein Anruf wie

%Vor%

würde zu

expandieren %Vor%

Es würde also eine neue Hashtabelle erstellen und diese der Variablen zuweisen, anstatt einfach ein Element zu aktualisieren. Keine weise Sache zu tun ...

    
Martin Odersky 21.04.2010 16:24
quelle
6

Aus der Programmierung in Scala, Kapitel 17:

  

Immer wenn du ein + = b schreibst, und ein tut   unterstützt keine Methode namens + =, Scala   werde versuchen, es als a = a + b zu interpretieren.

Die Klasse Int enthält keine Methode += . Die Klasse A stellt jedoch += method bereit. Das könnte die implizite Konvertierung von Int nach A auslösen.

    
missingfaktor 21.04.2010 13:26
quelle
3

Ich glaube nicht, dass es ein Fehler ist. Tatsächlich hat Int nur eine "+" - Methode, aber keine "+=" -Methode. b + = 1 würde sich in der Kompilierzeit in b = b + 1 umwandeln, wenn es kein anderes implizites gibt, bei dem eine "+=" - Methode existiert.

    
Eastsun 21.04.2010 13:23
quelle
1
  

Scala scheint der impliziten Konvertierung gegenüber dem natürlichen += , das bereits in Int s definiert ist, eine hohe Priorität einzuräumen.

Über welche Version von Scala sprichst du? Ich kenne keine Version mit einer += -Methode für Int . Sicher, keine der noch unterstützten Versionen, das muss eine wirklich alte Version sein, die Sie dort haben.

Und da es keine += für Int gibt, aber Sie aufrufen eine += Methode für Int , versucht Scala, diese Typabhängigkeit über eine implizite Konvertierung zu erfüllen.

    
Jörg W Mittag 21.04.2010 14:01
quelle