Go-Slice
Slice ist ein dynamisches Array, das in Größe und Länge flexibel ist. Slice ist eine Referenz auf ein zugrunde liegendes Array.
Deklaration
Slices werden ohne Größe deklariert, im Gegensatz zu Arrays.
go
var s []intDies deklariert einen Slice von int-Werten.
Initialisierung
Slices können mit make oder Literal-Initialisierung erstellt werden.
go
// Mit make
s := make([]int, 5)
// Mit Literal
s := []int{1, 2, 3, 4, 5}Slice von Array
Ein Slice kann aus einem Array erstellt werden.
go
a := [5]int{1, 2, 3, 4, 5}
s := a[1:4] // [2 3 4]Operationen
Länge und Kapazität
go
s := []int{1, 2, 3, 4, 5}
fmt.Println(len(s)) // 5
fmt.Println(cap(s)) // 5len(): Gibt die Länge des Slices zurückcap(): Gibt die Kapazität des Slices zurück
Anhängen
go
s := []int{1, 2, 3}
s = append(s, 4)
s = append(s, 5, 6)
fmt.Println(s) // [1 2 3 4 5 6]Kopieren
go
s1 := []int{1, 2, 3}
s2 := make([]int, 3)
copy(s2, s1)
fmt.Println(s2) // [1 2 3]Slice-Operationen
Slicing
go
s := []int{1, 2, 3, 4, 5}
s1 := s[1:3] // [2 3]
s2 := s[:3] // [1 2 3]
s3 := s[1:] // [2 3 4 5]
s4 := s[:] // [1 2 3 4 5]Slice als Stack
go
s := []int{1, 2, 3}
// Push
s = append(s, 4)
// Pop
last := s[len(s)-1]
s = s[:len(s)-1]nil Slice
Ein nil Slice hat keine Elemente.
go
var s []int
fmt.Println(s == nil) // true
fmt.Println(len(s)) // 0Slice und Array
Der Hauptunterschied zwischen Slice und Array ist:
| Array | Slice |
|---|---|
| Feste Größe | Dynamische Größe |
| Werttyp | Referenztyp |
len(a) ist Teil des Typs | len(s) ist zur Laufzeit |
Slice von Slices
Slices können verschachtelt werden.
go
s := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
fmt.Println(s[1][2]) // 6Slice und Funktionen
Slices werden als Referenz an Funktionen übergeben.
go
func main() {
s := []int{1, 2, 3}
modify(s)
fmt.Println(s) // [100 2 3]
}
func modify(s []int) {
s[0] = 100
}Kapazitätserweiterung
Wenn die Kapazität eines Slices überschritten wird, wird automatisch ein neues Array allokiert.
go
s := make([]int, 0, 2)
s = append(s, 1)
s = append(s, 2)
s = append(s, 3) // Neue Kapazität wird allokiertDie Kapazitätserweiterungsstrategie ist:
- Wenn die Kapazität weniger als 256 ist, verdoppelt sich die Kapazität
- Wenn die Kapazität 256 oder mehr ist, erhöht sich die Kapazität um 25%
Slice-Tricks
Entfernen eines Elements
go
s := []int{1, 2, 3, 4, 5}
// Entfernen des Elements an Index 2
s = append(s[:2], s[3:]...)
fmt.Println(s) // [1 2 4 5]Filtern
go
s := []int{1, 2, 3, 4, 5}
filtered := s[:0]
for _, v := range s {
if v%2 == 0 {
filtered = append(filtered, v)
}
}
fmt.Println(filtered) // [2 4]Umkehren
go
s := []int{1, 2, 3, 4, 5}
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
fmt.Println(s) // [5 4 3 2 1]