In meinem letzten Beitrag habe ich ausführlich beschrieben, wie Sie die Funktionen map und flatMap von Swift Optionals verwenden können. In diesem Beitrag füge ich Optionals über eine Erweiterung eine eigene Funktion hinzu, die ifPresent-Funktion. [code language="obj-c"] extension Optional { public func ifPresent(@noescape f: (Wrapped) throws -> Void) rethrows { switch self { case .Some(let value): try f(value) case .None: () } } } [/code]
Dabei wird einfach die Schließung ausgeführt f aus, wenn das Optional nicht Null ist. Ein kleines Beispiel: [code language="obj-c"] var str: String? = "Hallo, Spielplatz" str.ifPresent { print($0) } [/code] Dies funktioniert ziemlich genau so wie die Funktion ifPresent Methode von Java-Optionals.
Warum brauchen wir sie?
Nun, wir brauchen es nicht wirklich. Swift hat die eingebaute Sprachfunktion von if let und guard die mit dieser Art von Situationen ziemlich gut umgehen kann (was Java nicht kann). Wir könnten das obige Beispiel einfach wie folgt schreiben: [code language="obj-c"] var str: String? = "Hallo, Spielplatz" if let str = str { print(str) } [/code] Für dieses Beispiel spielt es keine große Rolle, ob Sie ifPresent oder ifLet. Und weil jeder mit if let sollten Sie wahrscheinlich dabei bleiben.
Wann Sie es verwenden sollten
Manchmal, wenn Sie eine Funktion aufrufen möchten, die genau einen Parameter mit demselben Typ wie Ihr Optional hat, dann können Sie von dieser Syntax etwas mehr profitieren. Schauen wir uns das mal an: [code language="obj-c"] var someOptionalView: UIView? = ... var parentView: UIView = ... someOptionalView.ifPresent(parentView.addSubview) [/code] Seit addSubview einen Parameter vom Typ UIView hat, können wir diese Funktionsreferenz sofort an die Funktion ifPresent Funktion übergeben. Andernfalls müssten wir stattdessen den folgenden Code schreiben: [code language="obj-c"] var someOptionalView: UIView? = ... var parentView: UIView = ... if let someOptionalView = someOptionalView { parentView.addSubview(someOptionalView) } [/code]
Wenn Sie es nicht benutzen können
Leider ist es nicht immer möglich, dies so zu nutzen, wie wir es gerne hätten. Wenn wir uns das allererste Beispiel mit der Option drucken Funktion zurückblicken, würden wir es idealerweise ohne Closure schreiben: [code language="obj-c"] var str: String? = "Hallo, Spielplatz" str.ifPresent(print) [/code] Auch wenn drucken nur mit einem String aufgerufen werden kann, nimmt seine Funktionssignatur variable Argumente und Standardparameter an. Wenn das der Fall ist, ist es nicht möglich, sie als Funktionsreferenz zu verwenden. Das wird zunehmend frustrierend, wenn Sie Standardparameter zu bestehenden Methoden hinzufügen, woraufhin Ihr Code, der sich darauf bezieht, nicht mehr kompiliert werden kann. Es wäre auch nützlich, wenn es möglich wäre, Klassenvariablen über eine Methodenreferenz zu setzen. Anstelle von: [code language="obj-c"] if let value = someOptionalValue { self.value = value } [/code] Wir würden etwas in dieser Art schreiben: [code language="obj-c"] someOptionalValue.ifPresent(self.value) [/code] Aber das lässt sich nicht kompilieren, also müssen wir es so schreiben: [code language="obj-c"] someOptionalValue.ifPresent { self.value = $0 } [/code] Was nicht wirklich viel besser ist als die if-Let Variante. (Ich habe mir einen Beitrag über den If-Let-Zuweisungsoperator angesehen, aber leider stürzte mein Swift-Compiler beim Erstellen ab, was wahrscheinlich auf einen Compiler-Bug zurückzuführen ist)
Fazit
Ist die ifPresent Funktion ein großer Fortschritt für Swift? Definitiv nicht. Ist sie notwendig? Nein. Kann sie nützlich sein? Ja.
Verfasst von

Lammert Westerhoff
Contact