yp des generischen impliziten Parameters vom Rückgabetyp übernehm
Sag ich habe eine einfache Klasse wie diese
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
Wenn val @ deklariert wif2
, der Compiler kann darauf schließen, dass der Typ des impliziten Parameters der Funktionf
istInt
da dieser Typ mit dem Ergebnistyp identisch ist und der Ergebnistyp mit dem Werttyp übereinstimmen mussf2
, welches istInt
.
Allerdings werfen einOrdering[A]
in die Mischung:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
Ergebnisse in diesem Kompilierungsfehler:
Ambiguous implizite Werte: beide Werte StringCanBuildFrom im Objekt Predef vom Typ => scala.collection.generic.CanBuildFrom [String, Char, String] und method $ entsprechen dem Objekt Predef vom Typ [A] => <: <[A, A ] entspricht dem erwarteten Typ A
Wenn ich beim Aufrufen von @ die Typinformationen hinzufüf()
, es kompiliert:
val f2: Int = f[Int]()
Zunächst bin ich auf den Fall mit impliziter Reihenfolge gestoßen, und ich dachte, dass dies damit zusammenhängt, dass Scala von links nach rechts ableitet. Ich dachte, es ist nicht in der Lage, den Rückgabetyp zuerst und @ zu entsprechdan auf den (impliziten) Parametertyp von @ schließf
. Aber dann habe ich versucht, den Fall ohne implizite Bestellung und sah, dass es funktioniert - es folgerte, dassf
muss mit @ parametriert werdInt
weil der Rückgabetyp ein @ sein muInt
(weilf2
ist einInt
).
Beachten Sie, dass, wenn wir @ entfernimplicit a: A
und lasse nur den impliziten Parameter Ordering, der Fehler bleibt bestehen, wird aber zu
Abweichende implizite Erweiterung für den Typ Ordering [A] beginnend mit der Methode Tuple9 im Objekt Ordering.
Again, Typparameter hinzufügen, so dass er zu @ wival f2: Int = f[Int]()
hilft.
Was ist los? Warum kann der Compiler diesen Parameter auf @ schließeA
muss ein @ seInt
, aber nicht dieser ParameterOrdering[A]
muss ein @ seOrdering[Int]
?