Warum ist die implizite Konvertierung von Long auf RichLong nicht angewandt, wo ein übergeordneten Typ von RichLong erwartet?
-
01-10-2019 - |
Frage
Scala 2.8 Spezifikation sagt in Abschnitt 7.3 (Hervorhebung von mir):
Implizite Parameter und Methoden können auch implizite Konvertierungen genannt Ansichten definieren. Ein Blick vom Typ S T zu geben ist durch einen impliziten Wert definiert, den Funktionstyp hat S => T oder (=> S) => T oder durch ein Verfahren, umwandelbar in einen Wert dieses Typs. Ansichten werden in zwei Situationen angewandt.
- Wenn ein Ausdruck e vom Typ T ist und T entspricht nicht , um den Gesichtsausdruck der erwartete Typ pt. In diesem Fall wird ein implizites v gesucht was anwendbar ist e und , deren Konform Ergebnistyp zu pt. Die Suche geht, wie im Fall von implizite Parameter, wobei der implizite Umfang das eines von T => pt ist. Wenn eine solche Ansicht gefunden wird, wird der Ausdruck e v umgewandelt (e).
[...]
angesichts der oben und die folgenden Fakten:
-
Long
kein Subtyp vonjava.lang.Comparable[Long]
ist, das heißt entspricht nichtT
geben, woT <: java.lang.Comaparable[Long]
-
Predef
enthältimplicit def longWrapper (x: Long) : RichLong
-
RichLong
ist ein Subtyp vonjava.lang.Comparable[Long]
, d.h. KonformT
geben, woT <: java.lang.Comaparable[Long]
Ich würde erwarten, dass die implizite Konvertierung angewandt werden, wo Long
angetroffen wird und ein Subtyp von java.lang.Comparable[Long]
erwartet wird. Allerdings:
scala> def test[T <: java.lang.Comparable[Long]](c: T) = println(c)
test: [T <: java.lang.Comparable[Long]](c: T)Unit
scala> test(12L)
<console>:7: error: inferred type arguments [Long] do not conform to method test's type parameter bounds [T <: java.lang
.Comparable[Long]]
test(12L)
^
Das Ergebnis ist wie erwartet, wenn der Wert explizit umgewandelt wird:
scala> test(longWrapper(12L))
12
Warum wird die Konvertierungsfunktion angewendet implizit?
Lösung
Sie benötigen einen Blick gebunden (<%
) zu verwenden, um Compiler Blick zu haben und die implizite Konvertierung anwenden.
scala> def test[T <% java.lang.Comparable[Long]](c: T) = println(c)
test: [T](c: T)(implicit evidence$1: (T) => java.lang.Comparable[Long])Unit
scala> test(12L)
12
Sie können lesen Sie mehr über Ansicht gebunden auf dieser Seite (Ctrl + F für "Ansicht gebunden").