Kotlin: Wie übergibt man eine Funktion als Parameter? Wir schauen es uns anhand von Beispielen an
\n\nHallo, Freund! Wenn du jemals in Kotlin programmiert und dich gefragt hast: "Wie übergibt man eine Funktion als Parameter an eine andere Funktion?" — dann bist du hier genau richtig. Diese Frage auf Stack Overflow hat tausende Aufrufe gesammelt, und das ist nicht verwunderlich. Funktionale Programmierung in Kotlin ist nicht nur eine modische Spielerei, sondern ein mächtiges Werkzeug, das Code sauberer, kürzer und ausdrucksstärker macht.
\n\nIn diesem Artikel geben wir nicht nur eine trockene Antwort. Wir werden alles von einfachen Lambda-Ausdrücken bis hin zu fortgeschrittenen Techniken durchgehen. Du wirst lernen, wie man Function-Typen, den Funktionsreferenz-Operator :: verwendet und sogar typische Anfängerfehler vermeidet. Los geht's!
Warum ist das wichtig? Drei Gründe, Funktionen als Parameter zu verwenden
\n\n- \n
- Flexibilität: Du kannst eine Funktion schreiben, die je nach übergebener Funktion unterschiedliche Dinge tut. \n
- Lesbarkeit: Der Code wird deklarativ – du beschreibst was zu tun ist, nicht wie. \n
- Wiederverwendbarkeit: Du vermeidest Code-Duplizierung, indem du gemeinsame Muster in Higher-Order-Funktionen auslagerst. \n
Grundlagen: Funktionstypen (Function Types)
\n\nIn Kotlin sind Funktionen First-Class-Objekte. Das bedeutet, sie haben einen eigenen Typ. Der Typ einer Funktion wird so beschrieben: (Parameter) -> Rückgabetyp. Zum Beispiel:
// Eine Funktion, die einen Int nimmt und einen String zurückgibt\nval intToString: (Int) -> String = { number -> "Zahl: $number" }\n\n// Eine Funktion, die nichts nimmt und nichts zurückgibt\nval doNothing: () -> Unit = { println("Hallo!") }\n\n// Eine Funktion mit zwei Parametern\nval sum: (Int, Int) -> Int = { a, b -> a + b }\n\n\nBeachte Unit – das ist das Äquivalent zu void in Java/JavaScript. Wenn eine Funktion nichts zurückgibt, ist ihr Typ () -> Unit.
Wie übergibt man eine Funktion als Parameter: Erstes Beispiel
\n\nAngenommen, wir schreiben eine Funktion, die eine Operation zweimal auf eine Zahl anwendet. Anstatt die Operation fest zu codieren, übergeben wir sie als Parameter:
\n\nfun applyTwice(x: Int, operation: (Int) -> Int): Int {\n val firstResult = operation(x)\n return operation(firstResult)\n}\n\n// Verwendung:\nval result = applyTwice(5) { it * 2 } // Lambda\nprintln(result) // Gibt aus: 20 (5*2 = 10, 10*2 = 20)\n\n// Oder mit einer benannten Funktion:\nfun double(x: Int) = x * 2\nval result2 = applyTwice(5, ::double)\nprintln(result2) // Ebenfalls 20\n\n\nSiehst du, wie elegant das ist? Im ersten Fall haben wir einen Lambda-Ausdruck (eine anonyme Funktion) verwendet, im zweiten eine Referenz auf eine bestehende Funktion mit dem Operator ::. Beide Methoden sind gültig, und wir werden sie genauer betrachten.
Methoden zur Übergabe von Funktionen (detaillierte Betrachtung)
\n\n1. Lambda-Ausdrücke (die beliebteste Methode)
\n\nEin Lambda ist eine anonyme Funktion, die direkt übergeben werden kann. In Kotlin haben Lambdas eine prägnante Syntax:
\n\nval list = listOf(1, 2, 3, 4, 5)\n\n// Lambda an die filter-Funktion übergeben\nval evenNumbers = list.filter { it % 2 == 0 }\nprintln(evenNumbers) // [2, 4]\n\n// Bei mehreren Parametern:\nval numbersWithIndex = list.mapIndexed { index, value -> "$index: $value" }\nprintln(numbersWithIndex) // ["0: 1", "1: 2", ...]\n\n\nWichtig: Wenn das Lambda der letzte Parameter einer Funktion ist, kann es außerhalb der Klammern stehen. Das lässt den Code wie eingebaute Sprachkonstrukte aussehen. Genau so funktionieren filter, map, forEach und andere.
Beispiel mit expliziter Parameterangabe (wenn es mehr als einen Parameter gibt):
\n\nfun performAction(a: Int, b: Int, action: (Int, Int) -> String) {\n println(action(a, b))\n}\n\n// Aufruf mit Lambda\nperformAction(3, 4) { x, y -> "Summe: ${x + y}" }\n