Die Magie von Swift wird durch Closures deutlich. Dabei handelt es sich um anonyme Funktionen. Soweit nichts aufregendes. Das findest Du auch in anderen Sprachen, z.B. als Lambda Funktionen. In Objective-C sind Blöcke den Closures sehr ähnlich. Faszinierend ist wie Swift mit der Syntax umgeht, sie interpretiert und Vereinfachungen ermöglicht. In diesem Artikel findest Du ein Beispiel dazu.

Closures sind Funktionen

Stell Dir zunächst eine normale Funktion vor. Die hat einen Namen (hier „meinSortierer“), möglicherweise Parameter (hier „s1“ und „s2“) sowie einen Rückgabewert (hier „Bool“):

Der Funktion übergibst Du zwei Strings. Über „kleiner als“ werden sie alphabetisch verglichen und das Ergebnis zurückgegeben. Merke: „A“ ist kleiner als „B“. Es wird in aufsteigender Reihenfolge sortiert – beginnend bei „A“. Swift bringt eine Methode mit, mit der Du bspw. Arrays  sortieren kannst. Der Methode übergibst Du die Funktion:

In der Variable „sortiert“ stehen nun die Namen – alphabetisch sortiert. Soweit, so gut.

Closure Ausdrücke

Das Beispiel könnte für sich genommen bereits verwendet werden. Gerade wenn Du eine zentrale Sortierfunktion festlegst, z.B. in Form einer Methode, kannst Du sie überall in Deiner App wieder verwenden. Nur für einmal sortieren jedoch eventuell übertrieben. Swift hat das Ziel den Code schlank zu halten. Und genau das geht hier über einen Closure Ausdruck. Die Syntax dafür sieht wie folgt aus (Quelle: Swift Language Guide von Apple):

swift closure syntax

Statt eine eigene Funktion zu erstellen, legst Du sie direkt beim Aufruf von „sorted“ fest. Der Kopf der Funktion (Definition der Parameter und Rückgabetyp) sind gleich. Eingeleitet wird die Funktion durch das Keyword „in“. Hier ein Beispiel:

Es passiert genau das gleiche wie weiter oben. Und jetzt schlägt die Optimierung zum ersten Mal zu: Bei diesem Konstrukt kannst Du die runden Klammern beim Aufruf von „sorted“ weglassen. Es wird kein weiteres Argument übergeben:

Apple spricht dabei von „trailing closures“.

Automatische Erkennung der Datentypen

Das ist noch gar nicht so spektakulär. Zumindest würde ich Deine Zeit nicht vergeuden und total begeistert einen kompletten Artikel darüber verfassen. Jetzt kommt der erste Paukenschlag. Swift kann selbst erkennen welche Typen die Parameter und der Rückgabewert haben – weil klar ist was für eine Funktion „sorted“ als Parameter erwartet. Die muss wie folgt aussehen:

Das übertragt Swift einfach auf den Closure Ausdruck. Die explizite Annotation fällt weg. Es wird also um einiges leichter:

Das ist mal kurz! Aber – es geht noch weiter.

Single-Expression Closures

Wir haben nur einen einzelnen Ausdruck. Wir vergleichen mittels „kleiner als“ und geben unmittelbar über „return“ true oder false zurück. Ein einzelner Ausdruck, auf englisch „Single-Expression“. In dem Fall musst Du das Keyword „return“ gar nicht mehr angeben:

Jetzt wird die Syntax noch klarer. Du musst Dir nur merken, dass die Rückgabe trotzdem erfolgt. Geht da noch etwas?

Abgekürzte Parameter

Wir legen im Beispiel explizit die Parameternamen „s1“ und „s2“ fest. Anschließend können wir sie in unserem Vergleich verwenden. Selbst das ist nicht notwendig. Sogenannte „Shorthand Argument Names“ erlauben den Verzicht auf explizite Parameter. So kannst Du unmittelbar vergleichen:

Wie bei einem Array ist das erste Element unter dem Index 0, das zweite unter dem Index 1 usw. erreichbar. Über ein Dollarzeichen sprichst Du die Parameter direkt an und kannst auch auf das Keyword „in“ ebenfalls verzichten.

Das war’s! Oder?

Operator Funktionen

Nicht ganz! Es geht noch kürzer! Swift weiß über die erforderlichen Parameter bescheid, kennt den Typ und erwartet insgesamt zwei. Somit muss gar nicht mehr der Parameter explizit genannt werden. Um den ersten mit dem zweiten Argument zu vergleichen, nutzt Du einfach Operator Funktionen:

Achtung: Hier sind nun runde Klammern gefragt. Aber: Wie abgefahren, oder? Du hättest auch einfach lesen können, Vergleiche funktionieren als Parameter „>“ oder „<„. Das würde aber die Technik dahinter im Dunkeln lassen. Schon abgefahren, was möglich ist.

Fazit zu Closures

Du kannst sie als Parameter übergeben, weiter durchreichen und – wie in Blöcken unter Objective-C – sogar Bezug auf den Variablen im Scope der Definition nehmen. Das ist dann wann anders Thema in einem neuen Artikel. Für den Moment gehört die Bühne dem Grad Optimierung. Solange klar ist was dabei passiert, kein Problem. Solche Kniffe daher unbedingt im Hinterkopf behalten, falls die Sortierfunktion mal geändert werden soll.

Tags:

Schreib einen Kommentar

Your email address will not be published.