Wie funktioniert Scalas Magie der Methode apply ()?


79

Wenn ich in Scala eine Methode definiere, die applyin einer Klasse oder einem Objekt der obersten Ebene aufgerufen wird, wird diese Methode immer dann aufgerufen, wenn ich ein Paar in Klammern an eine Instanz dieser Klasse anhänge und die entsprechenden Argumente apply()dazwischen setze . Zum Beispiel:

class Foo(x: Int) {
    def apply(y: Int) = {
        x*x + y*y
    }
}

val f = new Foo(3)
f(4)   // returns 25

Also im Grunde object(args)ist nur syntaktischer Zucker für object.apply(args).

Wie macht Scala diese Konvertierung?

Gibt es hier eine global definierte implizite Konvertierung, ähnlich den impliziten Typkonvertierungen im Predef-Objekt (jedoch in der Art unterschiedlich)? Oder ist es eine tiefere Magie? Ich frage, weil es den Anschein hat, als würde Scala die konsequente Anwendung eines kleineren Regelwerks nachdrücklich befürworten, anstatt viele Regeln mit vielen Ausnahmen. Dies scheint mir zunächst eine Ausnahme zu sein.


Antworten:


67

Ich glaube nicht , dass es etwas tiefer geht als das, was Sie ursprünglich gesagt haben: es ist nur syntaktischer Zucker , wobei der Compiler wandelt f(a)in f.apply(a)eine spezielle Syntax Fall.

Dies scheint eine bestimmte Regel zu sein, aber nur wenige davon (z. B. mit update) ermöglichen DSL- ähnliche Konstrukte und Bibliotheken.


4
Ich würde hinzufügen "wann fist ein Objekt (einschließlich Funktionen)". Wann fist eine Methode, gibt es offensichtlich keine solche Übersetzung.
Alexey Romanov

2
@AlexeyRomanov: Nun, wenn fes sich um eine Methode handelt, die ohne Parameterliste definiert ist, f(a)wird sie tatsächlich als so etwas interpretiert val _tmp = f; _tmp.apply(a). Aber das kommt wirklich fest in das Gebiet der Haarspalterei.
Jörg W Mittag

20

Es ist tatsächlich umgekehrt, ein Objekt oder eine Klasse mit einer Apply-Methode ist der Normalfall und eine Funktion ist eine Möglichkeit, implizit ein gleichnamiges Objekt mit einer Apply-Methode zu konstruieren. Tatsächlich ist jede von Ihnen definierte Funktion ein Unterobjekt des Merkmals Funktion n (n ist die Anzahl der Argumente).

Weitere Informationen zum Thema finden Sie in Abschnitt 6.6: Funktionsanwendungen der Scala-Sprachspezifikation .


+1 zum Ändern der Scala-Sprachspezifikation. Ich habe den richtigen Speicherort hinzugefügt, da Ihre Seitenzahl veraltet ist.
Alexandre Martins

8

Ich frage, weil es den Anschein hat, als würde Scala die konsequente Anwendung eines kleineren Regelwerks nachdrücklich befürworten, anstatt viele Regeln mit vielen Ausnahmen.

Ja. Und diese Regel gehört zu dieser kleineren Menge.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.