Kapitel 2: Grundlagen / 2.9 Optionals / 2.9.1 Deklaration von Optionals

Variablen oder Konstanten in Swift, so wie Sie sie bisher kennengelernt haben, also z.B. Int oder String müssen immer einen Wert enthalten, sie können nicht keinen Wert enthalten.

Um dennoch die Möglichkeit zu schaffen, dass eine Variable oder Konstante auch keinen Wert enthalten kann, existiert von jedem Datentyp eine optionale Variante: Es gibt einen optionalen String, ein optinales Integer, ein optionales Boolean usw.

Diese optionalen Varianten der Datentypen sind zwar mit ihrem jeweiligen nicht-optionalen Pendant eng verbunden, aber es sind doch eigene Datentypen.

Das Optional zu einem Datentyp schreibt sich mit einem Fragezeichen am Ende des jeweiligen Typs: Ein optionales Int schreibt sich Int? und ein optionaler String wird zu String?. Einen Optional deklarieren Sie genauso wie eine normale Variable oder Konstante:

var einOptionalerString: String? = "Kathryn"
var einOptionalerInteger: Int? = nil

Der Wert kein Wert heißt in Swift also nil, wie auch schon in Objective-C, und er kann wie jeder andere Wert einer Variablen oder Konstanten zugewiesen werden.

Die Type Inference funktioniert bei Optionals aus naheliegenden Gründen nicht:

var einString = "Kathryn"
var einBoolean = nil

Die Variable einString wird von Swift schlicht zu String inferiert, da der Compiler nicht wissen kann, dass wir lieber ein Optional gehabt hätten. Und die Variablendeklaration von einBoolean lässt zwar durch die Angabe von nil keinen Zweifel darüber aufkommen, dass wir gern ein Optional hätten, aber der Typ bleibt unklar, da nil für jeden Typ den Wert kein Wert beschreibt. Die zweite Zeile führt also folgerichtig zu einem Fehler.

Allerdings können Sie bei der Deklaration eines Optionals den Wert weglassen. Er wird dann automatisch auf nil gesetzt:

var einOptionalerBoolean: Bool?
println(einOptionalerBoolean)

Führt zu der schlichten Ausgabe:

nil

Was passiert, wenn Sie auf diese Weise eine Konstante statt einer Variablen deklarieren? Überlegen Sie kurz und lesen Sie erst dann weiter.

let einOptionalerBoolean: Bool?

Diese Codezeile ist technisch korrekt und dementsprechend wirft der Compiler auch keinen Fehler. Aber sie hat ein logisches Problem: Eine Konstante kann später nicht mehr geändert werden, also hängt die Konstante einOptionalerBoolean ewig auf nil fest. Sie können Sie also lediglich so benutzen, wie sie das Schlüsselwort nil selbst benutzen, Sie haben praktisch ein Kopie von nil in der Geschmacksrichtung Bool erzeugt. Der Compiler geht davon aus, dass das so nicht gewollt sein kann und schreibt eine Warning an die Codezeile:

Immutable value is default initialized and can never be changed.

Ein unveränderlicher Wert wurde mit dem Default (nämlich nil) initialisiert. Ein Defaultwert ist ganz allgemein ein Wert, der vom System angenommen wird, weil nichts anderes angegeben wurde.

Und eine Warning ist so etwas wie eine halbe Exception: Sie verhindert nicht, dass der Code compiliert werden kann, aber in Ordnung ist sie trotzdem nicht. Wenn Sie ein komplexes Programm compilieren, haben Sie sicherlich während der Entwicklung aus unterschiedlichen Gründen Warnings angesammelt, die werden Ihnen von Xcode dann nach dem Compilieren präsentiert. Aufgeführt sind dann u.a. Variablen, die sie zwar deklariert haben, aber nie benutzen oder Codeblöcke, die nie durchlaufen werden können, aber auch Warnings, die sie selbst gesetzt haben, um sich zum Beispiel eindringlich daran zu erinnern, dass an dieser Codestelle noch etwas zu tun ist. Wenn Sie Ihr Programm dann veröffentlichen, zum Beispiel indem Sie es in den App Store stellen, dann sollten sie als einen der letzten Programmierschritte alle Warnings entfernen.

Angenommen, Sie wollen trotzdem, aus guten Gründen, eine Konstante auf nil setzen, dann weisen Sie nil einfach explizit zu, dann gibt der Compiler auch keine Warning mehr aus:

let einOptionalerBoolean: Bool? = nil

 

Kapitel 2.9.1: Deklaration von Optionals

Schreibe einen Kommentar

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