Slice ist ein dynamisches Array, die grundlegende Struktureinheit bei der Arbeit mit Arrays in Go. Historizität boten Programmiersprachen feste Arrays oder schwerere Strukturen an. Go hat Slices als benutzerfreundliches Werkzeug zur Verarbeitung von Speicher-Kollektionen mit automatischer Größenverwaltung und der Möglichkeit, die Länge zu ändern, implementiert.
Problem besteht im richtigen Umgang mit Speicher, der Handhabung von Randfällen (leere, nil, volle Slices) und dem Verständnis des Unterschieds zwischen Länge und Kapazität eines Slices.
Lösung — die eingebauten Funktionen len() und cap() richtig zu verwenden und mit Slices gemäß den Go-Vereinbarungen zu arbeiten.
Beispielcode:
var a []int // nil slice, len=0, cap=0 b := make([]int, 0) // leeres slice, len=0, cap=0 c := make([]int, 3, 5) // len=3, cap=5 c = append(c, 4, 5, 6) // cap erhöht sich automatisch
Wesentliche Merkmale:
var s []int) reserviert überhaupt keinen Speicher, unterscheidet sich intern nur von einem leeren Slice (make([]int, 0)).Wie lang und kapazitätsreich wird ein Slice nach dem append an einen nil slice?
Ein nil slice (var s []int) wird nach append(s, 1) zu einem Slice der Länge 1 und Kapazität 1 — Go reserviert selbst den Speicher.
var s []int s = append(s, 42) // s ist jetzt [42], len=1, cap=1
Kann man auf die Kapazität eines nil Slices zugreifen?
Ja, bei einem nil slice geben beide Funktionen — len und cap — 0 zurück. Es wird keine Panik ausgelöst.
var s []int fmt.Println(len(s), cap(s)) // 0 0
Was passiert, wenn man versucht, einem Index eines nil Slices ohne vorherige Speicherzuweisung einen Wert zuzuweisen?
Es tritt eine Panik index out of range auf, da das Slice keine Elemente hat.
var s []int s[0] = 1 // panic: runtime error: index out of range
Das Team beschloss, im Go-Server überall nur var s []T zu verwenden, in der Erwartung, dass dies immer gleichwertig mit make([]T, 0) ist. Infolgedessen gaben einige JSON-Marshalisierungen null zurück und nicht [].
Vorteile:
Nachteile:
Verwendung von make([]T, 0, 100) zur Vorab-Zuweisung und danach nur append in der Schleife. So werden Speicherzuweisungen minimiert und oft wird die Leistung verbessert.
Vorteile:
Nachteile: