Konnte mir jemand folgende Situation mit Scala impliziten Konvertierungs-Mechanismus erklären. Es gibt einen Code:Frage über Scala implizite Konvertierungen Non-Ambiguity Rule
object Main {
implicit val x:Int => String = v => "val"
implicit def y(v:Int) = "def"
def p(s:String) = print(s)
def main(args: Array[String]): Unit = {
p(1)
}
}
Dieser Code druckt "val". Aber wenn ich zweite Zeile kommentiere:
//implicit val x:Int => String = v => "val"
Code druckt "def".
Somit sind beide impliziten Konvertierungen (x und y) in dieser Situation möglich. Es gibt eine Nicht-Mehrdeutigkeitsregel - eine implizite Konvertierung wird nur eingefügt, wenn keine andere mögliche Konvertierung zum Einfügen vorhanden ist. Nach dieser Regel sollte dieser Code überhaupt nicht kompiliert werden. Aber der Code wurde erfolgreich kompiliert und ausgeführt. Was ich nicht verstehe?
Danke.
Hallo Moritz. Danke für die Antwort. Wenn also der Scala - Compiler einen Ausdruck sieht, dessen Typ nicht mit einem erwarteten Typ übereinstimmt, sucht er nach impliziten Konvertierungen vom Typ T => F. Wenn solche Konvertierungen nicht gefunden werden, versucht der Compiler Eta Expansion oder Empty Application nach verfügbaren Methodenausdrücken auszuführen Das Wort "Sonst" in der Scala-Sprachspezifikation sagt, dass diese Aktion danach ausgeführt wird). Ob ich das alles verstanden habe? –
Aber in Ihrem Beispiel, wenn ich // implizite val t = "Welt" kommentieren, würde Code nicht kompiliert werden. Es scheint, dass Empty Application von Scala-Compiler hier nicht berücksichtigt wird. –
Leere Anwendung wird AFAICT tatsächlich nicht verwendet, wenn der Compiler nach impliziten Konvertierungen sucht, sondern nur zum Ausfüllen anderer impliziter Parameter. Wenn Sie 'implizit def i2s(): Int => String = _.toString 'schreiben, wird dies nicht als Kandidat für eine Umwandlung von' String' nach 'Int' betrachtet. Ansonsten ist es richtig - die Konvertierungen in der Liste in 6.26.2 werden von oben nach unten ausprobiert, wenn der Wert nicht direkt ausgewertet werden kann. – Moritz