Mathematiker haben ihre eigenen kleinen lustigen Wege. Anstatt zu sagen, "dann rufen wir die Funktion auf, f
indem wir sie x
als Parameter übergeben", wie wir Programmierer sagen würden, sprechen sie über "Anwenden der Funktion f
auf ihr Argument x
".
In Mathematik und Informatik ist Anwenden eine Funktion, die Funktionen auf Argumente anwendet.
Wikipedia
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 einen Int
Parameter akzeptiert und einen zurückgibt Int
, den OO-Typ von Function1[Int,Int]
.
// define a function in scala
(x:Int) => x + 1
// assign an object representing the function to a variable
val f = (x:Int) => x + 1
Da in Scala alles ein Objekt ist, f
kann es jetzt als Referenz auf ein Function1[Int,Int]
Objekt behandelt werden. Zum Beispiel können wir toString
Methoden aufrufen , von denen geerbt Any
wurde, was für eine reine Funktion unmöglich gewesen wäre, weil Funktionen keine Methoden haben:
f.toString
Oder wir könnten ein anderes Function1[Int,Int]
Objekt definieren, indem wir compose
method on aufrufen f
und zwei verschiedene Funktionen miteinander verketten:
val f2 = f.compose((x:Int) => x - 1)
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 das Function1[Int,Int]
Objekt aufrufen :
f2.apply(2)
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 als f(args)
. Hier greift der Scala-Compiler ein, und wenn wir einen Verweis f
auf ein Funktionsobjekt haben und schreiben f (args)
, um Argumente auf die dargestellte Funktion anzuwenden, erweitert der Compiler f (args)
den Objektmethodenaufruf stillschweigend f.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:
// we will be able to use this object as a function, as well as an object
object Foo {
var y = 5
def apply (x: Int) = x + y
}
Foo (1) // using Foo object in function notation
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:
List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation
// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3)
Die apply
Methode ist also nur eine praktische Möglichkeit, die Lücke zwischen Funktionen und Objekten in Scala zu schließen.