Slices in Go sind eines der mächtigsten, aber auch heimtückischsten Werkzeuge der Sprache. Auf den ersten Blick scheinen sie nur „dynamische Arrays“ zu sein, aber unter der Haube haben sie genug Nuancen, um eine Codezeile in einen Bug zu verwandeln, dessen Debugging mehrere Stunden dauert. Lassen Sie uns herausfinden, wie sie tatsächlich funktionieren.

Woraus besteht ein Schnitt?
Ein Slice in Go ist kein Array. Dies ist eine "dünne Hülle", die Folgendes speichert:
Zeiger auf ein Array — der tatsächliche Speicherort der Daten.
Länge (len) — wie viele Elemente gerade verfügbar sind.
Kapazität (cap) - wie viele Elemente können ohne Speicherzuweisung gespeichert werden.
s := []int{1, 2, 3, 4}
fmt.Println(len(s)) // 4
fmt.Println(cap(s)) // 4
Kapazität und ihre Rolle
Kapazität ist ein Vorrat. Wenn wir append machen, prüft Go:
Wenn die Kapazität ausreicht, werden neue Elemente einfach in dasselbe Array geschrieben.
Wenn die Kapazität aufgebraucht ist, erstellt Go neues größeres Array und kopiert alte Daten dorthin.
s := make([]int, 2, 4) // len=2, cap=4
s = append(s, 10, 20) // es gibt noch genügend Plätze
fmt.Println(cap(s)) // 4
s = append(s, 30) // cap ist zu Ende → neues Array
fmt.Println(cap(s)) // 8Copy und Fallstricke
Die Funktion copy führt eine oberflächliche Kopie durch:
a := []int{1, 2, 3}
b := make([]int, len(a))
copy(b, a)
b[0] = 99
fmt.Println(a) // [1 2 3]
fmt.Println(b) // [99 2 3]Aber wenn Sie einfach zuweisen:
a := []int{1, 2, 3}
b := a
b[0] = 99
fmt.Println(a) // [99 2 3] ❗Hier zeigen a und b auf dasselbe Array — ein häufiger Anfängerfehler.

Grow: Wie Slices wachsen
Go garantiert keinen genauen Wachstumsalgorithmus, funktioniert aber normalerweise wie folgt:
Wenn die Kapazität klein ist, verdoppelt sie sich.
Wenn die Kapazität bereits groß ist, erhöht sie sich um etwa 25 %.
👉 Daher ist es bei der Arbeit mit großen Datenmengen besser, make([]T, 0, N) im Voraus mit der erforderlichen Reserve zuzuweisen.
Fallstricke: Wo Entwickler am häufigsten scheitern
Allgemeines zugrunde liegendes Array
a := []int{1, 2, 3, 4, 5} b := a[:3] c := a[2:] c[0] = 99 fmt.Println(b) // [1 2 99] 😱bundcverwenden dasselbe Array.Das Wachstum bricht die „Verbindung“
a := []int{1, 2, 3} b := a a = append(a, 4) // cap erschöpft → neues Array b[0] = 99 fmt.Println(a) // [1 2 3 4] fmt.Println(b) // [99 2 3]Nach dem Wachstum hat
abereits ein anderes Array, und die Verbindung zubist verloren gegangen.Schnitte eines großen Arrays
big := make([]byte, 1e6) small := big[:1] // small sieht winzig aus, speichert aber den gesamten MegabyteLösung:
copyin einen neuen Slice.
Ergebnis
Schnitte in Go sind ein praktisches Tool, aber:
Denken Sie an Kapazität und Wachstum,
verwenden Sie
copy, wenn Sie unabhängige Daten wünschen,Vorsicht mit "Schnitten von Schnitten".
Wenn Sie verstehen, wie die Slices unter der Haube funktionieren, werden Sie unerwartete Fehler vermeiden und zuverlässigeren Code schreiben können.
