Scala Language
Funktion höherer Ordnung
Suche…
Bemerkungen
Scala legt großen Wert darauf, Methoden und Funktionen als syntaktisch identisch zu behandeln. Aber unter der Haube sind sie unterschiedliche Konzepte.
Eine Methode ist ausführbarer Code und hat keine Wertdarstellung.
Eine Funktion ist eine tatsächliche Objektinstanz des Typs Function1
(oder eines ähnlichen Typs einer anderen Art). Der Code ist in der apply
Methode enthalten. Im Grunde fungiert es einfach als Wert, der herumgereicht werden kann.
Im Übrigen ist genau die Fähigkeit , Funktionen als Werte zu behandeln , was durch eine Sprache gemeint ist die Unterstützung für Funktionen höherer Ordnung aufweist. Funktionsinstanzen sind Scalas Ansatz zur Implementierung dieser Funktion.
Eine tatsächliche Funktion höherer Ordnung ist eine Funktion, die entweder einen Funktionswert als Argument verwendet oder einen Funktionswert zurückgibt. Da in Scala alle Operationen Methoden sind, ist es allgemeiner, über Methoden nachzudenken, die Funktionsparameter empfangen oder zurückgeben. map
, wie in Seq
definiert, kann daher als "Funktion höherer Ordnung" betrachtet werden, da es sich bei seinem Parameter um eine Funktion handelt, aber es handelt sich nicht um eine Funktion. Es ist eine Methode.
Methoden als Funktionswerte verwenden
Der Scala-Compiler konvertiert Methoden automatisch in Funktionswerte, um sie an Funktionen höherer Ordnung zu übergeben.
object MyObject {
def mapMethod(input: Int): String = {
int.toString
}
}
Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")
Im obigen Beispiel ist MyObject.mapMethod
kein Funktionsaufruf, sondern wird stattdessen als Wert an map
. In der Tat erfordert map
einen Funktionswert, der an sie übergeben wird, wie aus der Signatur ersichtlich ist. Die Signatur für die map
einer List[A]
(eine Liste von Objekten des Typs A
) lautet:
def map[B](f: (A) ⇒ B): List[B]
Der Teil f: (A) => B
gibt an, dass der Parameter für diesen Methodenaufruf eine Funktion ist, die ein Objekt vom Typ A
übernimmt und ein Objekt vom Typ B
zurückgibt. A
und B
sind beliebig definiert. Wenn wir zum ersten Beispiel zurückkehren, können wir sehen, dass mapMethod
ein Int
(das A
) übernimmt und einen String
(der B
entspricht) zurückgibt. Daher ist mapMethod
ein gültiger Funktionswert, der an die map
. Wir könnten den gleichen Code wie folgt umschreiben:
Seq(1, 2, 3).map(x:Int => int.toString)
Dadurch wird der Funktionswert angezeigt, was für einfache Funktionen Klarheit schaffen kann.
Funktionen höherer Ordnung (Funktion als Parameter)
Eine Funktion höherer Ordnung kann im Gegensatz zu einer Funktion erster Ordnung eine von drei Formen haben:
Einer oder mehrere seiner Parameter ist eine Funktion und gibt einen Wert zurück.
Es gibt eine Funktion zurück, aber keiner seiner Parameter ist eine Funktion.
Beide der oben genannten: Einer oder mehrere seiner Parameter ist eine Funktion und gibt eine Funktion zurück.
object HOF { def main(args: Array[String]) { val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s")) //HOF val fullNameList= list.map(n => getFullName(n._1, n._2)) } def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName }
Hier verwendet die Map-Funktion eine getFullName(n._1,n._2)
Funktion getFullName(n._1,n._2)
als Parameter. Dies wird als HOF (Funktion höherer Ordnung) bezeichnet.
Argumente faul Auswertung
Scala unterstützt die verzögerte Auswertung von Funktionsargumenten mithilfe der Notation: def func(arg: => String)
. Ein solches Funktionsargument kann ein reguläres String
Objekt oder eine Funktion höherer Ordnung mit dem Rückgabetyp String
annehmen. Im zweiten Fall würde das Funktionsargument beim Zugriff auf Werte ausgewertet.
Bitte sehen Sie sich das Beispiel an:
def calculateData: String = {
print("Calculating expensive data! ")
"some expensive data"
}
def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
smartMediator(preconditions = false, calculateData)
dumbMediator(preconditions = false, calculateData)
smartMediator
Aufruf von smartMediator
würde None value zurückgeben und die Nachricht "Applying mediator"
smartMediator
.
dumbMediator
Aufruf von dumbMediator
würde None value zurückgeben und die Nachricht "Calculating expensive data! Applying mediator"
dumbMediator
.
Lazy Evaluation kann äußerst nützlich sein, wenn Sie den Aufwand für die Berechnung teurer Argumente optimieren möchten.