Tuple in Swift

Arrays oder Dictionaries wird jeder kennen, aber mit Tuples kommt man — als Anfänger — wohl eher selten in Berührung. Im Deutschen spricht man übrigens von einem Tupel. In diesem Artikel werde ich aber die englischen Bezeichnungen verwenden. Betrachten wir als Einstieg in dieses Thema zunächst einige Beispiele:

let numbers = (5, 24, 17)
let towns = ("Madrid", "Palermo")
let country = (name: "Spain", population: 46733038)

Die Werte werden — durch Kommata getrennt — von runden Klammern umschlossen. Wie anhand des Tuples, welches der Variable country zugewiesen wurde, erkennbar ist, können die Werte auch benannt sein (hier: name und population). Anhand des country-Tuples zeigt sich auch der Unterschied zum Array: Die Elemente eines Tuples können unterschiedlichen Typs sein (hier: String und Integer). Das ist bei einem Array grundsätzlich nicht der Fall; ein Array in Swift ist typensicher. Etwas anderes gilt aber dann, wenn man Any als Datentyp verwendet:

let mixedArray: [Any] = [1, "Text", 3.14]

Kommen wir aber zu den Tuples zurück. Die Werte eines Tuples können unterschiedlichen Variablen zugewiesen werden:

let (a, b) = towns
print(a) // -> Madrid
print(b) // -> Palermo

Es ist auch möglich, Tuples miteinander zu vergleichen:

(5, 24, 17) == (5, 24, 17) // -> true

Wie bereits das erste Beispiel gezeigt hat, kann man bei Tuples Bezeichnungen verwenden oder sie weglassen. Sehen wir uns dazu folgende Beispiele an:

let country = ("France", 643801)

Auf diese Werte kann über den Index zugegriffen werden:

print(country.0)
print(country.1)

Da in diesem Beispiel keine Bezeichnungen verwendet werden spricht man von einem Unnamed Tuple. Sobald Bezeichnungen verwendet werden, erhält man ein Named Tuple:

let country = (name: "France", area: 643801)

Auf diese beiden Werte kann über den Index oder die Bezeichnung zugegriffen werden:

print(country.name)
print(country.area)

print(country.0)
print(country.1)

Tuple können als Element auch ein Tuple enthalten. Dann spricht man von einem Nested Tuple.

let country = (
    name: "France",
    area: 643801,
    capital: ("Paris", 2150000)
)

Ein Tuple kann auch zusammen mit einem typealias zur Anwendung kommen, wie folgender Code demonstriert:

typealias Country = (name: String, area: Int)

func getCountry(_ name: String) -> Country {
    switch name {
    case "France":
        return ("France", 643801)
    case "Germany":
        return ("Germany", 357120)
    default:
        return ("Unknown", 0)
    }
}

print(getCountry("France").name)

In der Praxis sind sie sehr nützlich, da sie es ermöglichen, mehrere Werte von einem Funktionsaufruf zurückzugeben.