Generics in Swift: Wozu sie dienen und wie man sie verwendet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Was sind Generics und warum sind sie in Swift wichtig



Generics sind eine der leistungsstärksten und elegantesten Funktionen der Swift-Sprache. Sie ermöglichen es Ihnen, flexiblen, wiederverwendbaren Code zu schreiben, der mit jedem Datentyp funktioniert, während die starke Typisierung erhalten bleibt. Wenn Sie jemals Array<Int>, Dictionary<String, Any> oder Optional<T> verwendet haben — dann sind Sie bereits auf Generics gestoßen.



In diesem Artikel werden wir untersuchen, warum Generics in Swift benötigt werden, wie sie in der Praxis funktionieren, und Beispiele für die iOS/macOS-Entwicklung zeigen. Das Material wird sowohl für Anfänger als auch für erfahrene Entwickler nützlich sein, die ihr Wissen strukturieren möchten.



1. Warum werden Generics in Swift benötigt?



Der Hauptzweck von Generics besteht darin, Code-Duplizierung zu vermeiden und die Sicherheit zu verbessern. Stellen Sie sich vor, Sie müssen eine Funktion schreiben, die zwei Werte vertauscht. Ohne Generics müssten Sie separate Funktionen für Int, String, Double und so weiter erstellen:



func swapInts(_ a: inout Int, _ b: inout Int) {    let temp = a    a = b    b = temp}

func swapStrings(_ a: inout String, _ b: inout String) { let temp = a a = b b = temp}


Mit Generics wird diese Aufgabe mit einer universellen Funktion gelöst:



func swapValues<T>(_ a: inout T, _ b: inout T) {    let temp = a    a = b    b = temp}

var x = 10, y = 20swapValues(&x, &y) // x = 20, y = 10

var name1 = "Alice", name2 = "Bob"swapValues(&name1, &name2) // name1 = "Bob", name2 = "Alice"


Vorteile von Generics:

  • Code-Wiederverwendbarkeit: Eine Funktion/ein Typ funktioniert mit jedem Datentyp.
  • Typsicherheit: Der Compiler überprüft Typen zur Kompilierzeit, wodurch Laufzeitfehler vermieden werden.
  • Leistung: Generics in Swift werden durch Polymorphismus zur Kompilierzeit (Spezialisierung) implementiert, sodass kein Overhead durch Typumwandlung entsteht.
  • Lesbarkeit: Der Code wird abstrakter und prägnanter.


2. Generische Funktionen: Syntax und Beispiele



Eine generische Funktion wird mit spitzen Klammern <T> deklariert, wobei T ein Platzhalter für den Typ ist. Sie können jeden beliebigen Bezeichner verwenden: T, Element, Value usw.



Grundlegendes Beispiel: Finden des Index eines Elements



func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? {    for (index, item) in array.enumerated() {        if item == value {            return index        }    }    return nil}

let numbers = [1, 3, 5, 7, 9]if let index = findIndex(of: 5, in: numbers) { print("Index von Zahl 5: \\(index)") // Index von Zahl 5: 2}


Beachten Sie die Einschränkung <T: Equatable>. Dies ist eine Typeinschränkung. Sie teilt dem Compiler mit: "T muss dem Equatable-Protokoll entsprechen". Ohne diese Einschränkung wäre der ==-Operator nicht verfügbar.



Mehrere Typparameter



Sie können mehrere Typparameter verwenden:



func combine<T, U>(_ first: T, with second: U) -> String {    return "\\(first) + \\(second)"}

let result = combine(42, with: "answer")print(result) // 42 + answer


3. Generische Typen: Erstellen generischer Strukturen und Klassen



Generics gelten nicht nur für Funktionen, sondern auch für Typen. Das bekannteste Beispiel ist Array<Element>. Lassen Sie uns unsere eigene generische Struktur erstellen — einen Stack (LIFO):



struct Stack<Element> {    private var items: [Element] = []        mutating func push(_ item: Element) {        items.append(item                

Blogs

Buchempfehlungen