Optionals

Optionals sind ein grundlegendes Konzept in Swift. Die Entwickler von Swift sagen selbst das viele neue Möglichkeiten der Sprache ohne diesen Mechanismus nicht existieren könnten. Aber was sind Optionals? In dieser Lektion werden wir in einigen Beispielen unterschiedliche Szenarien und Möglichkeiten darstellen.

Optionals sind gerade für Anfänger kein leichtes Thema, dass in 2 Minuten erklärt sein wird. Nehmen Sie sich die Zeit um die Syntax und ihre Anwendungsmöglichkeiten zu verstehen.

Begriffserklärung

Optionals bieten uns die Möglichkeit Variablen oder Konstanten zu deklarieren ohne sie mit einem Wert zu initialisieren. Das bedeutet für uns das der Inhalt einer Variable vorhanden sein kann, aber nicht muss. “Nicht muss” ist hier entscheidend, da wir auf genau diesen Zustand prüfen. Sollte sich herausstellen das der Wert nicht existiert können wir entsprechend reagieren.

Mit Optionals können wir einem Programmcode flexibler gestalten. Ausserdem kann Swift durch dessen Typensicherheit mehr Fehlerschutz im Umgang mit Variablen und Konstanten bieten als Objective-C.

Für diesen Teil gibt es auch ein Video Tutorial hier auf YouTube.

Optional

Damit wir einen optionalen Wert deklarieren können müssen wir der Variable den Variablentyp immer mit angeben. Das haben wir schon mehrfach getan, jetzt kommt aber die Besonderheit hinzu das wir ein ? hinter den Typen schreiben.

In unserem Playground werden wir jetzt auf der rechten Seite keinen Zahlenwert sehen sonder nil. nil entspricht einem nicht-existenten Wert. Man kann ihn zum Beispiel vergleichen mit NULL aus der Programmiersprache C oder PHP. Der Inhalt der Variable ist also nicht-existent.

Was bringt mir dieser Zustand?
Es könnte z.B. sein das Ihr Benutzer auf Ihrer Programmoberfläche einen Wert eingeben soll. Wenn dieser Wert aber nicht existiert können Sie ihn auch nicht verwenden. Um auf Nummer sicher zu gehen, dass der Wert nicht existieren kann wird das im Textfield im Normfall als optional markiert.

Später werden wir das Verhalten auch sehen, wenn wir die erste iOS App mit UI Elementen schreiben . Diese sind bis zu ihrer Initialisierung nicht verfügbar, es könnte aber passieren das unser Code bereits auf diese Elemente zugreifen möchte. Dankbare Weise stürzt das Programm aber nicht ab da es bereits weiss, dass die Variable keinen Wert haben muss.

 

Wenn wir die Ausgabe von REPL im Playground ansehen werden wir feststellen, dass bei der Deklaration der Wert nil  ist. Sobald wir den Wert setzen wird REPL uns ausgeben, dass der Inhalt {Some 12}  ist. Im Anschluss setzen wir den Wert wieder auf nil , wodurch die Variable wieder leer ist.

LogicValue und unwrapped optionals

Warum gibt uns REPL bei unserem letzten Beispiel  {Some 12} aus (Ausgabe wie immer im Playground rechts sichtbar)? Dafür müssen wir ein wenig hinter die Kulissen von Swift kucken.

Optionals gibt es in zwei Ausprägungen. “Normal optional” und “Implicit unwrapped optionals”. Ein Optional, den wir durch das Fragezeichen markieren, wird nicht direkt als Wert der Variable gespeichert sondern in einem Datentyp (vereinfacht gesagt!), welcher den Zugriff auf diesen Wert regelt und kontrolliert. Dieser Datentyp gibt beim Zugriff immer einen Bool-Wert zurück. Dies geht aber nur mit Datentypen die das Protokoll LogicValue implementieren. Zu Protokollen kommen wir aber in einer anderen Lektion.

Um an den Wert eines optionals zu kommen muss man ihn erst einmal “auspacken“. Dies erreichen wir durch das “!” Zeichen.

Im Playground sehen wir rechts wieder das  meinString den Wert  {Some "Hallo"} hat. Möchten wir den Wert der Variable  meinString in einer anderen speichern die nicht optional ist, müssen wir diese zuerst “unwrappen” oder anderes ausgedrückt die Daten “auspacken”. Dies machen wir indem wir ein “!” hinter den Variablennamen schreiben, wo dieser entpackt werden soll.

Unsere zweite Variable  neuerString ist deklariert als String und erwartet einen solchen auch. Wir können nicht einfach den Wert einer andere Variable,  die als optional deklariert ist, speichern. Sollten wir das “!” Zeichen weglassen würde uns der Compiler das direkt als Fehler anzeigen.

Das kann uns natürlich später auch in unserem eigenen Programm passieren, wie in der Einleitung bereits erwähnt durch eine fehlende Benutzereingabe. Wie können wir es vermeiden, dass ein Wert entpackt wird der gar nicht existiert?

Swift bietet uns hierfür zwei Möglichkeiten. Da ein optional im Grunde ein  LogicValue ist können wir einfach mit einer Kontrollstruktur prüfen ob der Inhalt von  meinString existiert. Sollte dies der Fall sein, weisen wir  neuerString den Wert zu nachdem wir ihn mit dem “!”-Zeichen entpackt haben. Eine weitere Möglichkeit ist es eine temporäre Konstante zu erstellen und das direkt bei der Definition unserer Kontrollstruktur. Durch die Zuweisung eines optionals Wertes wird der Wert – von Swift selbst – beim vorhanden sein entpackt und hier in der Konstante  x gespeichert, sofern dieser nicht nil ist.

Im Anschluss können wir den Wert aus der Konstanten  x der Variable  neuerString zuweisen.

Sicherlich verwirrt dies den ein oder anderen ein wenig, aber mit etwas Übung und späteren arbeiten in Verbindung mit Apple’s Systembibliotheken (UIKit oder Cocoa) wird das ganze ein Kinderspiel.

Neben der Möglichkeit eine Variable als optional deklarieren, können wir auch auch sagen das diese “implicit unwrapped optional” ist. Das heißt, dass wir garantieren das hier bereits der ausgepackte Wert hinter dem Variablennamen verborgen ist oder dieser nil ist. Wir müssen ihn also nicht explizit entpacken. Wir bekommen auch keinen Fehler wenn wir versuchen  meinString , ohne das wir diese vorher in Kontrollstruktur geprüft haben, direkt der Variable  neuerString zuweisen. Das funktioniert aber natürlich nur solange  meinString nicht den Wert  nil hat.

 

Als Entwickler haben wir die Möglichkeit anderen Entwicklern, die vielleicht Teile unseres Programmecodes wiederverwenden, darauf hinzuweisen das einige Werte nicht vorhanden sein müssen. Es obliegt dann den anderen Entwicklern sicherzustellen, dass sie immer mit Werten arbeitet die auch Tatsächlich existieren. Sollten sie dies nicht tun, laufen sie Gefahr durch dieses Fehlverhalten ihre App mit Laufzeitfehlern abstürzten zu lassen. Sehr zum Ärgern des Endanwenders.

Optionals und Funktionen

Selbstverständlich können wir optionals auch bei Funktionen nutzen. Diese Technik kann sowohl bei den Parametern, als auch bei den Rückgabewerten genutzt werden. Man könnte z.B. einen Fehlerfall definieren indem eine Funktion anstelle von einem Bool einfach nil  zurückliefert. Dies kann Beispielsweise dann nützlich sein, wenn man eine Funktion hat die einen String zurückliefern soll.

Hierdurch ersparen wir uns nämlich ein Tuple, die uns sowohl einen Bool  als auch irgendeinen String  zurückliefern müsste. Schauen wir uns das folgende Beispiel mit optionals und ohne an.

Wer es vielleicht nicht direkt erkannt hat, wird feststellen das wir im Fehlerfall ohne optionals zusätzlich einen Bool  zurückliefern müssten. Man hätte auch auf die Stringlänge prüfen können, aber ein Fehler sollte auch eindeutig als Fehler erkennbar sein. Die Rückgabe mit dem Wert nil  eignet sich dafür in Swift am besten.

In Verbindung mit Protokollen beziehungsweise in Verbindung mit dem “Delegation pattern” spielen optionals erst richtig ihre Vorzüge aus. Dies wird ein wichtiger Bestandteil unseres folgenden Kapitel werden und schließt das Kapitel 2 hier ab.

Abschließendes zu Kapitel 2

Wir hoffen das Sie mit Kapitel 2 die wichtigsten Grundlagen der prozeduralen Programmierung verstanden haben. Mit dem aktuellen Fachwissen kann man jetzt noch keine komplette App bauen, aber mit dem nächsten Kapitel über Objektorientierung werden wir davon nur noch einen kleinen Schritt entfernt sein.

Wie immer hoffen wir für unseren Grundkurs auf Kritik und Verbesserungsvorschläge. Unser Ohr und E-Mail Postfach ist immer für Sie erreichbar.

Vielen Dank,

Stefan Popp & Ralf Peters

Previous post

Swift lernen: Type Alias

Next post

Swift Toolbox bündelt Swift Bibliotheken

The Author

Stefan Mayer-Popp

Stefan Mayer-Popp

Stefan Mayer-Popp ist leidenschaftlicher Softwareentwickler, Fachbuchautor, Trainer und Berater aus dem Münchner Umland. Als passionierter IT- und Apple-Profi hat Mayer-Popp unzählige IT-Projekte in verschiedensten Branchen erfolgreich umsetzen und unterstützen können. Neben seiner Tätigkeit als Teamleiter bei CHECK24 teilt Mayer-Popp seine Erfahrungen auf IT-Veranstaltungen und propagiert Swift aktiv auf verschiedenen Meetups.

15 Comments

  1. Filip Radic
    25. August 2014 at 18:08 — Antworten

    Hallo Swift-Blog,

    Ich wollte fragen ob ihr vielleicht nach jedem Kapitel einen kleinen Test machen könntet, damit man einfach sicher sein kann, dass man alles verstanden hat .

    • 27. August 2014 at 20:03 — Antworten

      Hallo Fillip,

      ich finde das ist eine ganz hervorragende Idee für die Anfängerkapitel und ich werde das in die Wege leiten. Danke für dein Feedback und den guten Tip.

      Liebe Grüße

      Ralf

  2. Achim
    9. Dezember 2014 at 10:57 — Antworten

    Hi,

    Super BLOG habe jetzt alle Tutorial die auf Schrift sind durchgegcukt und finde ich sehr NICE gemacht.

    Ich hoffe das es bald Kapitel 3 auch als Textform erscheinen wird. Denn ich finde Text besser als ein Video. Aber einige mögen es anders herum 🙂

    Danke für alles Jungs.

    LG
    Achim

  3. Stefan
    11. Januar 2015 at 20:19 — Antworten

    Danke für die Mühe!

    Euer Tut ist wirklich sehr nett zu lesen, auch die Videos sind sehr gut gelungen.

    Ich hoffe Ihr macht so weiter =)

    MfG,
    Stefan

    • 11. Januar 2015 at 22:27 — Antworten

      Wir bleiben am Ball und sind im Moment dabei neue Inhalt für die Veröffentlichung vorzubereiten.

      Vielen Dank für das Feedback!

  4. Horst
    20. Januar 2015 at 13:10 — Antworten

    Hallo,
    wenn ich im Playground u.a. Code eingebe, bekomme ich fgolgende Fehlermeldung. meinString sei kein Bool und könne so nicht auf Wahrheitsgehalt geprüft werden, besser sei eine Überprüfung mit:
    meinString != nil

    var neuerString: String // Deklaration ohne Initialisierung
    var meinString: String! = “Hallo” // Hallo
    meinString = nil // Variablen nil’len

    // Prüfen und zuweisen
    if meinString {
    neuerString = meinString
    }

    Hat sich da was geändert? Bitte um eine kurze Erklärung.

    Gruß Horst

    • 20. Januar 2015 at 18:13 — Antworten

      Hallo Horst,

      das Verhalten ist tatsächlich korrekt vom Compiler. Alternativ kannst du “Optional Binding” nutzen, mit dieser Technik wird ein String nur dann in eine temporäre Variable gespeichert, wenn der Wert auch tatsächlich existiert.

      Hier ein Beispiel:

      var neuerString: String // Deklaration ohne Initialisierung
      var meinString: String! = “Hallo” // Hallo
      meinString = nil // Variablen nil’len

      // Prüfen und zuweisen
      if let aString = meinString {
      neuerString = aString
      }

      Viele Grüße,
      Stefan

  5. Horst
    20. Januar 2015 at 22:07 — Antworten

    Hallo Stefan,

    danke für die schnelle Antwort.

    Gruß Horst

  6. Peter
    12. März 2015 at 15:46 — Antworten

    Hallo Stefan,

    Eure Tutorials sowie auch die Videos sind wirklich super gut erklärt. Habe soeben euer Buch “Durchstarten mit Swift” bei Amazon.de geordert.

    Ich hoffe, dass Ihr die Video-Tutorials weiter macht und freue mich schon auf die nächsten Videos und auch Tutorials!

    Viele Grüsse,
    Peter

    • 14. März 2015 at 1:07 — Antworten

      Hallo Peter,

      vielen Dank für dein Kommentar und danke (!!!) für den Kauf des Buches! Es wird natürlich weiter gehen, aber das Berufsleben erdrückt mich gerade immens. Ich habe bereits neue Videos aufgenommen und müsste diese nur noch schneiden. Es wird aber glücklicherweise gerade ruhiger und ich konnte schon bei den ersten beginnen 🙂

      Viele Grüße,
      Stefan

  7. Julian
    17. Juni 2015 at 16:29 — Antworten

    Hallo Stefan,
    ich bin vollkommener Swift-Neuling und bin gerade beim Basic Kapitel Schleifen angekommen. Wenn ich mich selbst im Playground ausprobiere, treffe ich immer wieder auf folgende Fehlermeldung:

    “Statement cannot begin with a clossure expression”

    Unten siehst du meinen Programmcode:
    for var trial = 0.5: Double; trial < 200; trial + 1.5: Double {
    println("That's my \(trial)")
    }

    Würde mich über eine Erklärung sehr freuen!
    Gruß Julian

    • Manuel
      29. Juni 2015 at 13:08 — Antworten

      Hallo bin zwar auch relativ neu in Swift aber denke dein code sollte so aussehen….for var trail:Double = 0.5;trail<200.0;trail += 1.5{
      println("That,s my \(trail)")
      }

    • Manuel
      29. Juni 2015 at 13:14 — Antworten

      Hallo bin zwar auch relativ neu in Swift aber denke dein code sollte so aussehen….for var trail = 0.5; trail<200; trail += 1.5 {
      println("That,s my \(trail)")
      }

  8. Artur
    29. Februar 2016 at 21:08 — Antworten

    Wahnsinn! Danke für diesen tollen Beitrag! Hat mir sehr geholfen!

  9. Markus
    6. Januar 2018 at 12:13 — Antworten

    Das ist nach längerer Suche der erste Beitrag, der mir Optionals verständlich erklärt! Vielen Dank!

Leave a reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.