© S&S Media Group
Kotlin kompakt - Teil 3

Kotlin Code verstehen: Higher-Order Functions


Higher-Order Functions

Jetzt wird es richtig interessant, und Kotlin lässt seine Muskeln spielen.

Wenn du dir das Beispiel betrachtest, wird dir sofort das val Keyword auffallen, gefolgt von einem Variablen-Namen. Wir haben es also grundsätzlich mit einer Variablen-Deklaration zu tun, die durch das = und den Code danach zur Definition wird.

Rufe dir nun noch in Erinnerung, dass strings eine Liste von Strings ist:

val strings = listOf("Hello", "World", "!") 

Auf diese rufen wir nun eine Methode namens map auf - doch das sieht für Java-Augen nun etwas komisch aus, und man könnte meinen, ich hätte mich vertippt und statt runder Klammern versehentlich geschweifte eingegeben. Aber was wie ein Tippfehler aussieht, entpuppt sich in Wahrheit als sehr häufiges und äußert elegantes Kotlin-Idiom.

Um dieses jedoch erläutern zu können, muss ich dir zunächst Higher-Order Functions vorstellen, falls du diese nicht bereits von anderen Sprachen her kennst. (Lambda-Expressions aus Java 8 lasse ich nicht als vollwertigen Ersatz gelten.)

Eine Higher-Order Function ist eine Funktion, die andere Funktion(en) als Argumente entgegennimmt, und/oder zurückgibt.

Das bedeutet, man kann in Kotlin eine Funktion an eine andere als Argument übergeben - und genau das tun wir in unserem Beispiel.

Die map-Methode ist Teil von strings (vielmehr von dessen Typ List<String>) in Kotlin. (Genauer gesagt handelt es sich dabei um eine sogenannte Extension Function des Typs Iterable<T> - solche Extension Functions sind ein weiteres sehr cleveres Konzept in Kotlin - doch dieses hier einzuführen, brächte uns abermals vom Weg ab, so dass ich dich nochmals um etwas Geduld bitten muss.)

Also kann man map auf strings aufrufen.

Falls es dir nicht bereits in Java 8+ untergekommen ist, fragst du dich sicher: "Was macht map überhaupt?"

Wie der Name vermuten lässt ("to map" = "abbilden"), bildet die Methode einen Wert auf einen anderen ab, oder "wandelt ihn um". Genauer gesagt, ruft man map auf einer Collection auf, wird jedes Element darin "transformiert", so dass eine neue Collection entsteht, die aus derselben Anzahl von Elementen besteht. Jedes davon jedoch nach den Regeln von map in einen neuen Wert umgewandelt.

Nächste Frage: "Was heißt 'transformiert'?". Gute Frage!

Genau das ist es, was wir mithilfe von map selbst festlegen können. Dazu akzeptiert map eine andere Funktion, die wiederum genau ein Element der Liste (in unserem Falle also einen String, da wir map auf eine Liste von Strings aufrufen) als Argument entgegen nimmt, und "etwas anderes" zurück gibt.

Beispielsweise könnten wir eine einfache Transformations-Funktion schreiben, die einen String entgegennimmt und dessen Länge zurückgibt (Int).

Das ist ganz einfach, und mit dem Wissen aus den vorherigen Abschnitten kannst du diese vielleicht sogar schon selbst formulieren, ganz sicher aber verstehen:

fun getLengthOfString(str: String): Int { return str.length } 

(Der einzige Stolperstein mag length statt length() sein. Warum das so ist, erfährst du im Kapitel über Properties.)

So weit, so gut.

Nun ist alles, was wir tun müssen, diese Funktion an map zu übergeben. map wird daraufhin alle Elemente in strings durchgehen, und für jedes davon unsere übergebene Funktion aufrufen. Dazu übergibt es das Element - also einen String - an unsere "Transformations-Funktion" und nimmt als Rückgabewert dessen Länge - einen Int entgegen.

Aber wie genau machen wir das?

Weil Kotlin ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang