Generics und Typisierung in Swift: Wie man Code schreibt, der für einen arbeitet

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

Warum Ihr Swift-Code ohne Generics bald zu Spaghetti wird

\n\n

Stellen Sie sich vor, Sie schreiben eine App für die Pizzalieferung. Sie müssen Bestellungen, Kunden, Fahrer verarbeiten – und jedes Mal denselben Code für Sortierung, Suche oder Filterung schreiben, wobei Sie nur den Datentyp ändern? Klingt nach dem Albtraum eines jeden Entwicklers. Genau hier kommen Generics in Swift ins Spiel – ein mächtiges Werkzeug, das es Ihnen ermöglicht, flexiblen, wiederverwendbaren Code zu schreiben, ohne die Typsicherheit zu opfern.

\n\n

In diesem Artikel gehen wir nicht nur die Syntax durch. Wir werden analysieren, wie Typisierung in Swift und Generics zusammenarbeiten, damit Ihr Code nicht nur schön, sondern auch zuverlässig ist. Sie erfahren, wie Sie Copy-Paste vermeiden, wie Sie protocol mit associatedtype verwenden und warum where-Klauseln Ihr bester Freund sind.

\n\n

Was sind Generics und warum ändern sie die Spielregeln

\n\n

Generics (generische Typen) sind ein Mechanismus, der es ermöglicht, Funktionen, Strukturen, Klassen und Aufzählungen zu schreiben, die mit jedem Datentyp arbeiten, der bestimmte Bedingungen erfüllt. Anstatt drei Versionen einer Funktion für Int, String und Double zu schreiben, schreiben Sie eine, die mit jedem Typ funktioniert.

\n\n

In Swift ist die Typisierung streng und statisch. Das bedeutet, der Compiler überprüft die Typen zur Kompilierzeit. Generics verletzen diese Regel nicht – sie machen sie flexibler. Der Compiler leitet den konkreten Typ beim Aufruf der Funktion selbst ab, aber die Überprüfungen bleiben bestehen.

\n\n

Erstes Beispiel: Funktion ohne Generics

\n\n
// Schlecht: drei Funktionen für drei Typen\nfunc swapInts(_ a: inout Int, _ b: inout Int) {\n    let temp = a\n    a = b\n    b = temp\n}\n\nfunc swapStrings(_ a: inout String, _ b: inout String) {\n    let temp = a\n    a = b\n    b = temp\n}\n\nfunc swapDoubles(_ a: inout Double, _ b: inout Double) {\n    let temp = a\n    a = b\n    b = temp\n}
\n\n

Und jetzt – die elegante Lösung mit Generics:

\n\n
// Gut: eine Funktion für alle Typen\nfunc swapValues<T>(_ a: inout T, _ b: inout T) {\n    let temp = a\n    a = b\n    b = temp\n}\n\n// Verwendung:\nvar x = 10\nvar y = 20\nswapValues(&x, &y) // T = Int\n\nvar name1 = "Alice"\nvar name2 = "Bob"\nswapValues(&name1, &name2) // T = String
\n\n

Sehen Sie die Magie? <T> ist ein Platzhalter für den Typ. Der Compiler setzt beim Aufruf den tatsächlichen Typ ein. Das ist die Grundlage der generischen Programmierung in Swift.

\n\n

Generische Typen: Erstellen Sie Ihren eigenen universellen Stack

\n\n

Generics in Swift funktionieren nicht nur mit Funktionen, sondern auch mit ganzen Typen. Lassen Sie uns eine Stack-Struktur erstellen – das klassische Beispiel einer LIFO-Datenstruktur (Last In, First Out).

\n\n
struct Stack<Element> {\n    private var items: [Element] = []\n    \n    mutating func push(_ item: Element) {\n        items.append(item)\n    }\n    \n    mutating func pop() -> Element? {\n        return items.popLast()\n    }\n    \n    func peek() -> Element? {\n        return items.last\n    }\n    \n    var count: Int {\n        return items.count\n    }\n}\n\n// Verwendung:\nvar intStack = Stack<Int>()\nintStack.push(1)\nintStack.push(2)\nintStack.push(3)\nprint(intStack.pop() ?? 0) // 3\n\nvar stringStack = Stack<String>()\nstringStack.push("Swift")\nstringStack.push("Generics")\nprint(stringStack.peek() ?? "") // "Generics"
\n\n

Beachten Sie: Den Typ Element geben wir in spitzen Klammern bei der Deklaration der Struktur an. Bei der Erstellung einer Instanz konkretisieren wir ihn – Stack<Int> oder Stack<String>. Der Compiler garantiert, dass Sie nicht versehentlich einen String in einen Integer-Stack legen können.

\n\n

Protocol mit associatedtype: Generics für Protokolle

\n\n

In Swift können Protokolle nicht direkt generische Parameter haben. Stattdessen verwenden

Blogs

Buchempfehlungen