Junior
Wie funktionieren Slices in Go?
sobes.tech KI
Antwort von AI
Ein Slice ist eine leichte Hülle über einem Array. Es speichert keine Daten selbst, sondern verweist auf ein Basarray.
Struktur des Slices:
- Zeiger auf das Basarray: Adresse des ersten Elements des Slices im Speicher.
- Länge (Length): Anzahl der Elemente im Slice.
- Kapazität (Capacity): Anzahl der Elemente im Basarray, die ab dem Zeiger des Slices verfügbar sind.
// Beispiel für die Deklaration eines Slices
var s []int
s = append(s, 1, 2, 3) // Elemente hinzufügen
// Interne Darstellung des Slices s (vereinfachte Version)
// struct SliceHeader {
// Data uintptr // Zeiger auf das Basarray
// Len int // Länge des Slices
// Cap int // Kapazität des Slices
// }
- Beim Erstellen eines Slices mit
make([]T, length, capacity)wird ein Basarray mit der angegebenen Kapazität erstellt, und ein Slice, das darauf verweist, mit der angegebenen Länge. - Beim Verwenden eines Slices auf einem Array oder einem anderen Slice (z.B.
arr[low:high:max]) wird ein neuer Slice erstellt, der auf denselben Speicherbereich des Basarrays verweist, aber mit anderen Zeigern, Länge und Kapazität. - Die Operation
appendkann eine Speicherneuzuordnung verursachen. Wenn die aktuelle Kapazität nicht ausreicht, um neue Elemente hinzuzufügen, erstellt Go ein neues, größeres Basarray, kopiert die alten Elemente hinein und aktualisiert den Zeiger des Slices auf das neue Array. Dies wird Reallokation genannt. Das Wachstum der Kapazität beim Append ist exponentiell (verdoppelt sich bis zu einer bestimmten Größe, dann verlangsamt sich das Wachstum). - Slices werden per Wert übergeben, aber da sie einen Zeiger auf das Basarray enthalten, sind Änderungen an den Elementen des Slices (über den Index) in allen Slices sichtbar, die auf dasselbe Basarray verweisen.
- Das Ändern der Länge des Slices durch einen Slice schneidet das Basarray nicht an, kann aber den Zugriff auf einen Teil der Daten im Basarray einschränken.
Tabelle: Vergleich von Length und Capacity
| Merkmal | Länge (Length) | Kapazität (Capacity) |
|---|---|---|
| Definition | Tatsächliche Anzahl der Elemente im Slice | Maximale Anzahl der Elemente, die im Slice ohne Reallokation sein können |
| Zugriff | Wird zum Zugriff auf Elemente verwendet (s[i]) | Bestimmt, wie viele weitere Elemente mit append hinzugefügt werden können, bevor eine Reallokation erfolgt |
| Ermittlung | len(s) |
cap(s) |
// Beispiel für die Arbeit mit Kapazität und Länge
s := make([]int, 0, 5) // Länge 0, Kapazität 5
fmt.Println(len(s), cap(s)) // 0 5
s = append(s, 1, 2) // Zwei Elemente hinzufügen
fmt.Println(len(s), cap(s)) // 2 5
s = append(s, 3, 4, 5, 6) // Weitere 4 Elemente hinzufügen, benötigt Reallokation
fmt.Println(len(s), cap(s)) // 6 10 (Kapazität erhöht sich)