Strings in Swift: Warum substring nicht so funktioniert, wie du es gewohnt bist?

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: Die "Falle", die jeden Swift-Entwickler erwartet

\n\n

Stell dir vor: Du schreibst selbstbewusst Code in Swift, alles läuft rund, und dann musst du die ersten drei Zeichen aus einem String holen. Du schreibst, ohne nachzudenken, so etwas wie myString[0..<3] – und erhältst... einen Kompilierungsfehler. Kommt dir bekannt vor?

\n\n

Willkommen in der Welt von String substring in Swift. Das ist eines dieser Themen, das Anfängern und sogar erfahrenen Entwicklern, die von anderen Sprachen wechseln, echte Kopfschmerzen bereitet. Die Frage "How does String substring work in Swift" hat auf Stack Overflow tausende Aufrufe – und das nicht ohne Grund.

\n\n

In diesem Artikel werden wir analysieren, warum Swift so "seltsam" bei der Arbeit mit Teilstrings ist, wie man substring in Swift richtig verwendet und welche neuen Möglichkeiten in den letzten Versionen hinzugekommen sind. Los geht's!

\n\n

Warum erlaubt Swift nicht einfach, ein Stück eines Strings herauszuschneiden?

\n\n

In den meisten Sprachen (Python, JavaScript, C#) ist ein String einfach ein Array von Zeichen. Du willst einen Teilstring? Schreibe str[0:3] und erhalte das Ergebnis. In Swift ist alles anders.

\n\n

Der Grund liegt in der Arbeit mit Unicode. Strings in Swift sind nicht einfach Bytes oder ASCII-Zeichen. Sie bestehen aus Graphem-Clustern (grapheme clusters). Ein einzelnes Zeichen, das der Benutzer sieht (z.B. "é" oder "👍🏽"), kann mehrere Character oder sogar mehrere Unicode.Scalar belegen. Stell dir vor, du schneidest einen String mitten in einem solchen Cluster ab – du erhältst beschädigte Daten.

\n\n

Deshalb verwendet Swift Indizes (String.Index) anstelle von ganzen Zahlen. Dies stellt sicher, dass du niemals ein Zeichen in der Mitte durchtrennst.

\n\n

Grundlagen: String.Index und einfaches Extrahieren eines Teilstrings

\n\n

Beginnen wir mit einem einfachen Beispiel. Angenommen, wir haben einen String:

\n\n
let fullString = "Привет, Swift!"\n// Wir wollen das Wort "Swift" nehmen\nlet startIndex = fullString.index(fullString.startIndex, offsetBy: 8)\nlet endIndex = fullString.index(fullString.startIndex, offsetBy: 13)\nlet substring = fullString[startIndex..<endIndex]\nprint(substring) // Gibt aus: "Swift"
\n\n

Beachte: substring hat den Typ Substring, nicht String. Das ist ein wichtiger Unterschied. Substring ist ein "Fenster" in den ursprünglichen String. Es kopiert keine Daten, sondern verweist lediglich auf einen Teil des Speichers des ursprünglichen Strings. Das ist super effizient, kann aber zu Speicherlecks führen, wenn der ursprüngliche String groß und der Teilstring klein ist.

\n\n

Um einen Substring in einen vollwertigen String umzuwandeln, verwende einfach den Initialisierer:

\n\n
let newString = String(substring)\nprint(newString) // "Swift"
\n\n

Syntaktischer Zucker: RangeExpression

\n\n

Jedes Mal index(offsetBy:) zu schreiben, ist mühsam. Glücklicherweise erlaubt Swift kürzere Formen mit RangeExpression.

\n\n

Der Operator ... (ClosedRange)

\n
let str = "Hello, World!"\nif let range = str.range(of: "World") {\n    let worldSubstring = str[range]\n    print(worldSubstring) // "World"\n}
\n\n

Partielle Bereiche (Partial Range)

\n

Du willst alles bis zu einem bestimmten Index oder danach nehmen? Einfach:

\n
let text = "Swift Programming"\nlet prefix = text[..<text.index(text.startIndex, offsetBy: 5)]\nprint(prefix) // "Swift"\n\nlet suffix = text[text.index(text.startIndex, offsetBy: 6)...]\nprint(suffix) // "Programming"
\n\n

Beachte: prefix und suffix sind ebenfalls Substring.

\n\n

Eingebaute Methoden: prefix, suffix, dropFirst, dropLast

\n\n

Swift bietet praktische Methoden, die die manuelle Berechnung von Indizes überflüssig machen. Sie geben Substring zurück.

\n\n