robust-co.de

– Robuster Code mit Swift

Robuster Code mit Swift

27.07.2014

Apples neue Programmiersprache Swift produziert schon vor ihrer offiziellen Einführung im Herbst viel Wind. Dieser Eintrag soll zeigen, wie uns Swift helfen kann, robuster zu programmieren.

Optionale Typen

Die mächtigste Änderung zu den gängigen Programmiersprachen ist sicherlich die optionalen Typen. In den gängigen objektorientierten Sprachen wird ein Objekt über die Adresse im Speicher identifiziert, den es belegt. Wenn eine Methode mit einem Objekt aufgerufen wird, dann wird diese Adresse übergeben (oder auch „by reference“). Der reservierte Wert 0 steht dabei für „kein Objekt“.

Dies hat zwei Auswirkungen. Zum einen können nur Objekte weggelassen werden. Für Zeichen und Integer-Zahlen gibt es keinen Wert, der für kein Objekt steht, da eine 0 durchaus gewünscht sein kann.

Viel schlimmer wiegt jedoch, dass ein Objekt nicht gesetzt sein muss, auch wenn die aufgerufene Methode ohne dieses Objekt nicht arbeiten kann. Der Sourcecode wird durch die Prüfungen, ob die Instanzen wirklich vorhanden sind, umständlich aufgebläht.

Nehmen wir als Beispiel eine Methode, die in ein übergebenes Dictionary einen Eintrag einfügt. In Java könnte dies so aussehen:

void addSignature(Map<String, String> map) {
	if (map != null) {
		map.put("signature", "secret_signature");
	}
}

Wir die Prüfung weg gelassen, dann kann die Methode zur Laufzeit mit der beliebten NullPointerException auf die Nase fallen.

Nicht so in Swift.

Hier können Variablen nur dann den Wert nil bekommen, wenn sie als optional definiert wurden. Dies wird durch Anhängen des Fragezeichens an den Typnamen signalisiert.

Fehlt das Fragezeichen, dann kann der Typ nicht nil sein. Der Compiler stellt bereits sicher, dass die Methode nicht mit Werten aufgerufen wird, die nil sein könnten.

Damit reduziert sich das Beispiel zu

func addSignature(map: [String: String]) {
	map["signature"] = "secret_signature"
}

Swift folgt damit der Sprache Haskell und ist für die robuste Programmierung noch besser geeignet, als Objective-C mit seinem komfortablen Umgang mit nil.

Zwar ermöglicht auch Swift das direkte Auflösen von optionalen Typen. Dies wird wie Java mit einer Runtime-Exception bedient, wenn der Wert nil ist. Es gibt jedoch auch einen besseren Weg. Durch eine spezielle if Syntax kann ein Wert nur verwendet werden, wenn er gesetzt ist:

var x: String?
if let a = x {
	// a kann hier verwendet werden und
	// ist vom Typ String, nicht String?
}

Wenn man eine Methode auf einer Instanz nur aufrufen möchte, wenn sie gesetzt ist, kann eine optionale Auflösung wieder mit dem Fragezeichen verwendet werden.

a?.f("nur wenn a gesetzt ist")

Dadurch können die Zugriffe auf optionale Typen elegant gekapselt werden. In robusten Code sollte man auf die erzwungene Auflösung wenn möglich verzichten.

let und var

Als zweites Stilelement für die robuste Programmierung kann die Unterscheidung zwischen Variablen und Konstanten angesehen werden. Konstante Werte können nach der Zuweisung nicht geändert werden. Das macht den Code klarer und erlaubt dem Compiler tiefgreifendere Optimierungen.

Generics

Mit Generics können Typen in Collections angegeben werden. Dadurch muss der robuste Code nicht prüfen, ob zum Beispiel sich wirklich nur Strings in einem Array befinden. Diese Prüfung nimmt der Compiler ab.

Funktionen als Variablen

Zu guter Letzt bringt uns Swift näher an die funktionale Programmierung. Das ist für die robuste Programmierung sicher kein Nachteil.


Kommentare

Möchten Sie einen Beitrag korrigieren, ergänzen oder kommentieren? Senden Sie mir eine E-Mail an timm@robust-co.de. Interessante Beiträge veröffentliche ich gerne auf dieser Seite.