Ein Go-String ist eine unveränderliche Folge von Bytes, normalerweise UTF-8-Text. Die Operatoren arbeiten auf dem String selbst (+, ==, <, Indizieren, Slicen), und alles andere steckt im Standardpaket strings.
Strings splitten
| Funktion | Trennt an | Hinweise |
|---|---|---|
Split(s, sep) | jedem sep | behält leere Teile; Split("", ",") gibt [""] zurück, einen leeren String |
SplitN(s, sep, n) | höchstens n Teile | der letzte Teil enthält den Rest |
SplitAfter(s, sep) | jedem sep | behält das Trennzeichen an jedem Teil |
Fields(s) | Folgen von Leerraum | liefert nie leere Teile |
FieldsFunc(s, f) | Zeichen, für die f true ist | eigene Trennzeichen |
Cut(s, sep) | nur dem ersten sep | liefert davor, danach, gefunden (Go 1.18) |
Der Fall Split("", ",") erwischt viele: Eine leere Eingabe ergibt einen Slice der Länge 1, nicht 0. Beim Splitten von Nutzereingaben vermeidest du mit Fields oder einer vorherigen Prüfung auf s == "" ein Phantom-Element.
strings.Cut ist der sauberste Weg, key=value, user@host und ähnliche Paare zu trennen. Go 1.24 hat außerdem Iterator-Versionen eingeführt, strings.SplitSeq und strings.FieldsSeq, die die Teile einzeln liefern, ohne einen Slice zu bauen.
Suchen
| Funktion | Gibt zurück |
|---|---|
Contains(s, sub) | true, wenn sub in s vorkommt |
ContainsAny(s, chars) | true, wenn irgendein Zeichen aus chars vorkommt |
HasPrefix(s, p) / HasSuffix(s, p) | true, wenn s mit p beginnt oder endet |
Index(s, sub) | Byte-Position des ersten Treffers oder -1 |
LastIndex(s, sub) | Byte-Position des letzten Treffers oder -1 |
Count(s, sub) | Anzahl nicht überlappender Treffer |
EqualFold(a, b) | Gleichheit ohne Beachtung der Groß- und Kleinschreibung |
Jede Suche beachtet Groß- und Kleinschreibung, außer EqualFold. Um unabhängig davon zu suchen, wandle beide Seiten in Kleinbuchstaben um oder nimm EqualFold für Vergleiche ganzer Strings.
Umwandeln
Eine Falle: Trim, TrimLeft und TrimRight nehmen eine Menge von Zeichen, kein Präfix. strings.TrimLeft("abcab", "ab") entfernt jedes führende a und b und gibt "cab" zurück. Um ein exaktes Präfix oder Suffix zu entfernen, nimm TrimPrefix und TrimSuffix.
Verkettung und strings.Builder
+ verbindet Strings, und fmt.Sprintf formatiert Werte in einen String. Beide legen jedes Mal einen neuen String an, weil Strings unveränderlich sind. Für eine Handvoll Operationen ist das in Ordnung, in einer Schleife aber langsam, weil jedes += alles bisher Gebaute kopiert. Nimm stattdessen strings.Builder:
Ein strings.Builder mit Nullwert ist sofort einsatzbereit. Er implementiert io.Writer, also schreibt fmt.Fprintf direkt hinein. Ruf vorher b.Grow(n) auf, wenn du ungefähr weißt, wie groß das Ergebnis wird. Kopier einen Builder nicht, nachdem du hineingeschrieben hast; übergib einen Pointer.
Mehrzeilige und Raw Strings
Go hat zwei Arten von String-Literalen:
Strings in doppelten Anführungszeichen verarbeiten Escapes (\n, \t, \", \\, \u00e9) und müssen in eine Zeile passen. Raw Strings in Backquotes nehmen alles wörtlich, auch Zeilenumbrüche. Damit schreibst du mehrzeilige Strings, reguläre Ausdrücke, JSON und Windows-Pfade. Ein Raw String kann keinen Backquote enthalten, und Wagenrückläufe darin werden entfernt. Beachte, dass die Query oben mit einem Zeilenumbruch beginnt, da das Literal direkt nach dem öffnenden Backquote anfängt.
Länge, Indizes und Teilstrings
len(s) ist die Anzahl der Bytes. s[i] ist ein Byte, und s[i:j] ist ein Teilstring nach Byte-Positionen:
ï und é belegen je zwei Bytes, also hat der String 12 Bytes und 10 Zeichen. Nach Bytes zu slicen ist sicher, solange die Positionen von strings.Index oder Ähnlichem kommen, die Byte-Offsets auf Zeichengrenzen liefern. Für „die ersten n Zeichen“ konvertierst du vorher in []rune. Die Seite zu Runes und Bytes erklärt UTF-8 im Detail.
Strings sind unveränderlich
Du kannst ein Byte nicht direkt ändern: s[0] = 'H' ist ein Compilerfehler (cannot assign to s[0] (neither addressable nor a map index expression)). Jede Funktion in strings gibt einen neuen String zurück. Zum Bearbeiten konvertierst du in []byte oder []rune, änderst den Slice und konvertierst zurück:
b := []byte("hello")
b[0] = 'H'
s := string(b) // "Hello"
Die Unveränderlichkeit ist auch der Grund, warum Teilstrings billig sind: s[2:5] teilt sich den Speicher mit s, statt ihn zu kopieren. Die Kehrseite: Ein kleiner Teilstring eines riesigen Strings hält den ganzen riesigen String am Leben. Nimm strings.Clone (Go 1.20), wenn du ein kurzes Stück einer großen Eingabe behältst.
Strings vergleichen
== und != vergleichen den Inhalt, und <, > vergleichen Byte für Byte, was bei ASCII alphabetisch ist. strings.Compare gibt es, wird aber selten gebraucht; slices.Sort auf einem []string nutzt <. Für eine sprachabhängige Sortierung von nicht englischem Text nimm golang.org/x/text/collate.
Andere Typen konvertieren
Zahlen werden mit strconv.Itoa, strconv.FormatFloat oder fmt.Sprintf zu Strings, und Strings werden mit strconv.Atoi und strconv.ParseFloat zu Zahlen. Schreib nicht string(42): Das erzeugt das Zeichen mit Codepoint 42, "*". Die Seite zur Typkonvertierung hat die vollständige Tabelle.
Häufig gestellte Fragen
Wie splitte ich einen String in Go?
Mit strings.Split(s, sep): strings.Split("a,b,c", ",") gibt ["a" "b" "c"] zurück. Um an beliebigen Folgen von Leerraum zu trennen und leere Teile wegzulassen, nimm strings.Fields(s). strings.SplitN begrenzt die Anzahl der Teile, und strings.Cut trennt einmal am ersten Trennzeichen.
Wie schreibe ich einen mehrzeiligen String in Go?
Mit einem Raw-String-Literal in Backquotes:
query := `SELECT id, name
FROM users
WHERE active = true`
Alles zwischen den Backquotes wird wörtlich genommen, auch Zeilenumbrüche und Backslashes. Ein Raw String kann keinen Backquote enthalten.
Wie prüfe ich in Go, ob ein String einen Teilstring enthält?
strings.Contains(s, substr) gibt ein bool zurück. Verwandte Funktionen: strings.HasPrefix, strings.HasSuffix, strings.Index (Position oder -1), strings.ContainsAny (eines aus einer Menge von Zeichen) und strings.EqualFold für Gleichheit ohne Beachtung der Groß- und Kleinschreibung.
Wie verkettet man in Go am schnellsten Strings?
Für ein paar Strings ist + in Ordnung. Baust du einen String in einer Schleife auf, nimm strings.Builder: Ruf wiederholt WriteString auf und am Ende einmal String(). Wiederholtes += in einer Schleife kopiert jedes Mal den ganzen String und wird daher langsam, je größer der String wird. Um einen Slice mit Trennzeichen zu verbinden, nimm strings.Join.
Warum liefert len die falsche Länge für meinen String?
len(s) gibt die Anzahl der Bytes zurück, nicht der Zeichen. Go-Strings sind UTF-8, und Zeichen außerhalb von ASCII belegen 2 bis 4 Bytes, also ist len("héllo") 6. Für die Anzahl der Unicode-Codepoints nimm utf8.RuneCountInString(s).