Ich habe es nie anhand der erfundenen Beispiele für das Nicht-Marshalling und Verbieren von Substantiven (eine AddTwo
Klasse hat eine apply
, die zwei hinzufügt!) Verstanden .
Ich verstehe, dass es syntaktischer Zucker ist, also muss er (ich habe aus dem Kontext abgeleitet) entworfen worden sein, um Code intuitiver zu machen.
Welche Bedeutung hat eine Klasse mit einer apply
Funktion? Wofür wird es verwendet und zu welchen Zwecken verbessert es den Code (Unmarshalling, Verbing von Substantiven usw.)?
Wie hilft es, wenn es in einem Begleitobjekt verwendet wird?
Antworten:
Mathematiker haben ihre eigenen kleinen lustigen Wege. Anstatt zu sagen, "dann rufen wir die Funktion auf,
f
indem wir siex
als Parameter übergeben", wie wir Programmierer sagen würden, sprechen sie über "Anwenden der Funktionf
auf ihr Argumentx
".apply
dient dazu, die Lücke zwischen objektorientierten und funktionalen Paradigmen in Scala zu schließen. Jede Funktion in Scala kann als Objekt dargestellt werden. Jede Funktion hat auch einen OO-Typ: Zum Beispiel hat eine Funktion, die einenInt
Parameter akzeptiert und einen zurückgibtInt
, den OO-Typ vonFunction1[Int,Int]
.Da in Scala alles ein Objekt ist,
f
kann es jetzt als Referenz auf einFunction1[Int,Int]
Objekt behandelt werden. Zum Beispiel können wirtoString
Methoden aufrufen , von denen geerbtAny
wurde, was für eine reine Funktion unmöglich gewesen wäre, weil Funktionen keine Methoden haben:Oder wir könnten ein anderes
Function1[Int,Int]
Objekt definieren, indem wircompose
method on aufrufenf
und zwei verschiedene Funktionen miteinander verketten:Wenn wir nun die Funktion tatsächlich ausführen möchten oder als Mathematiker sagen "eine Funktion auf ihre Argumente anwenden" sagen, würden wir die
apply
Methode für dasFunction1[Int,Int]
Objekt aufrufen :Das Schreiben
f.apply(args)
jedes Mal, wenn Sie eine als Objekt dargestellte Funktion ausführen möchten, ist objektorientiert, würde dem Code jedoch viel Unordnung hinzufügen, ohne viele zusätzliche Informationen hinzuzufügen, und es wäre schön, wenn Sie mehr Standardnotation verwenden könnten, wie z alsf(args)
. Hier greift der Scala-Compiler ein, und wenn wir einen Verweisf
auf ein Funktionsobjekt haben und schreibenf (args)
, um Argumente auf die dargestellte Funktion anzuwenden, erweitert der Compilerf (args)
den Objektmethodenaufruf stillschweigendf.apply (args)
.Jede Funktion in Scala kann als Objekt behandelt werden und funktioniert auch andersherum - jedes Objekt kann als Funktion behandelt werden, sofern es über die
apply
Methode verfügt. Solche Objekte können in der Funktionsnotation verwendet werden:Es gibt viele Anwendungsfälle, in denen wir ein Objekt als Funktion behandeln möchten. Das häufigste Szenario ist ein Factory-Muster . Anstatt dem Code mithilfe einer Factory-Methode Unordnung hinzuzufügen, können wir
apply
einer Reihe von Argumenten widersprechen, um eine neue Instanz einer zugeordneten Klasse zu erstellen:Die
apply
Methode ist also nur eine praktische Möglichkeit, die Lücke zwischen Funktionen und Objekten in Scala zu schließen.quelle
class Average[YType](yZeroValue:YType)
. Wie übergeben Sie YType von seinem Objekt, da Objekte keine Typparameter annehmen können?apply
undunapply
Methoden. Wenn Sie also eine Klasse mit nur einer Zeile wie dieser definieren, könnencase class Car(make:String, model: String, year: Short, color: String)
Sie neue Objekte der Car-Klasse erstellen, indem Sie einfach :val myCar = Car("VW","Golf",1999,"Blue")
. Dies ist eine Abkürzung fürCar.apply(...)
every object can be treated as a function, provided it has the apply method
- So viel macht jetzt Sinn.Es kommt von der Idee, dass Sie oft etwas auf ein Objekt anwenden möchten . Das genauere Beispiel ist das der Fabriken. Wenn Sie eine Factory haben, möchten Sie Parameter darauf anwenden , um ein Objekt zu erstellen.
Scala-Leute dachten, dass es, wie es in vielen Situationen vorkommt, schön sein könnte, eine Abkürzung zum Anrufen zu haben
apply
. Wenn Sie also einem Objekt Parameter direkt zuweisen, wird es deaktiviert, als ob Sie diese Parameter an die Apply-Funktion dieses Objekts übergeben:Es wird häufig in Begleitobjekten verwendet, um eine nette Factory-Methode für eine Klasse oder ein Merkmal bereitzustellen. Hier ein Beispiel:
In der Scala-Standardbibliothek können Sie sich ansehen, wie
scala.collection.Seq
implementiert wird:Seq
Ist ein Merkmal, wird alsonew Seq(1, 2)
nicht kompiliert, aber dank des Companion-Objekts und der Anwendung können Sie es aufrufenSeq(1, 2)
und die Implementierung wird vom Companion-Objekt ausgewählt.quelle
Hier ist ein kleines Beispiel für diejenigen, die schnell lesen möchten
quelle