Arrays und Slices
Ein Array hat eine feste Länge (Teil des Typs). In der Praxis nutzt man fast immer Slices: dynamische Sichten auf Arrays.
package main
import "fmt"
func main() {
var a [3]int // Array: feste Länge, Nullwerte
a[0] = 10
fmt.Println(a, len(a))
s := []int{5, 3, 9} // Slice: wachsend
s = append(s, 1, 7)
fmt.Println(s, len(s), cap(s))
fmt.Println(s[1:3], s[:2], s[2:], s[len(s)-1])
leer := make([]int, 3, 10) // Länge 3, Kapazität 10
fmt.Println(leer, len(leer), cap(leer))
var nichts []int // nil-Slice: len 0, funktioniert mit append
fmt.Println(nichts == nil, len(nichts))
nichts = append(nichts, 1)
fmt.Println(nichts)
kopie := make([]int, len(s))
n := copy(kopie, s)
kopie[0] = 99
fmt.Println(n, s[0], kopie[0])
}[10 0 0] 3 [5 3 9 1 7] 5 6 [3 9] [5 3] [9 1 7] 7 [0 0 0] 3 10 true 0 [1] 5 5 99
| Operation | Bedeutung |
|---|---|
s[i] | Zugriff (außerhalb → Panic) |
s[a:b] | Teil-Slice von a bis vor b (teilt den Speicher!) |
append(s, x, y) | anhängen (kann neu allokieren) |
len(s), cap(s) | Länge, Kapazität |
copy(ziel, quelle) | kopieren |
make([]T, n, c) | anlegen |
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
teil := original[1:3]
teil[0] = 99
fmt.Println(original, teil)
teil = append(teil, 100) // überschreibt original[3]!
fmt.Println(original, teil)
sicher := append([]int(nil), original[1:3]...) // echte Kopie
sicher[0] = -1
fmt.Println(original[1], sicher[0])
}[1 99 3 4 5] [99 3] [1 99 3 100 5] [99 3 100] 99 -1
Slices bearbeiten
package main
import (
"fmt"
"slices"
"sort"
)
func main() {
z := []int{5, 3, 9, 1, 7}
slices.Sort(z)
fmt.Println(z, slices.Contains(z, 9), slices.Index(z, 7), slices.Max(z))
i, gefunden := slices.BinarySearch(z, 5)
fmt.Println(i, gefunden)
z = slices.Delete(z, 1, 3) // Elemente 1 und 2 löschen
fmt.Println(z)
z = slices.Insert(z, 1, 42)
fmt.Println(z)
namen := []string{"Zoe", "anna", "Ben"}
sort.Slice(namen, func(i, j int) bool { return len(namen[i]) < len(namen[j]) })
fmt.Println(namen)
slices.SortFunc(namen, func(a, b string) int { return len(b) - len(a) })
fmt.Println(namen)
matrix := [][]int{{1, 2}, {3, 4}}
fmt.Println(matrix[1][0], len(matrix))
}[1 3 5 7 9] true 3 9 2 true [1 7 9] [1 42 7 9] [Zoe Ben anna] [anna Zoe Ben] 3 2
Maps
Eine Map ordnet Schlüssel Werten zu:
package main
import (
"fmt"
"maps"
"slices"
"sort"
)
func main() {
alter := map[string]int{"Mia": 17, "Tom": 19}
alter["Zoe"] = 21
alter["Mia"] = 18
fmt.Println(alter["Mia"], alter["Unbekannt"], len(alter))
wert, vorhanden := alter["Max"] // "comma ok": unterscheidet 0 von "nicht da"
fmt.Println(wert, vorhanden)
if a, ok := alter["Zoe"]; ok {
fmt.Println("Zoe ist", a)
}
delete(alter, "Tom")
// Reihenfolge ist zufällig: für feste Ausgabe Schlüssel sortieren
schluessel := make([]string, 0, len(alter))
for k := range alter {
schluessel = append(schluessel, k)
}
sort.Strings(schluessel)
for _, k := range schluessel {
fmt.Print(k, "=", alter[k], " ")
}
fmt.Println()
fmt.Println(slices.Sorted(maps.Keys(alter)))
// Wörter zählen
zaehler := map[string]int{}
for _, w := range []string{"das", "ist", "das", "beste"} {
zaehler[w]++
}
fmt.Println(zaehler)
var nilMap map[string]int // nil-Map: Lesen ok, Schreiben = Panic
fmt.Println(nilMap["x"], len(nilMap))
gruppen := map[bool][]int{}
for _, n := range []int{1, 2, 3, 4, 5} {
gruppen[n%2 == 0] = append(gruppen[n%2 == 0], n)
}
fmt.Println(gruppen)
}18 0 3 0 false Zoe ist 21 Mia=18 Zoe=21 [Mia Zoe] map[beste:1 das:2 ist:1] 0 0 map[false:[1 3 5] true:[2 4]]
Die Iterationsreihenfolge einer Map ist absichtlich zufällig. fmt.Println auf einer Map gibt sie dagegen sortiert aus. Maps sind nicht threadsicher: Bei gleichzeitigem Zugriff brauchst du einen sync.Mutex oder sync.Map.
Mengen mit Maps
package main
import "fmt"
func main() {
menge := map[string]struct{}{} // struct{} belegt keinen Speicher
for _, w := range []string{"a", "b", "a", "c", "b"} {
menge[w] = struct{}{}
}
_, drin := menge["a"]
fmt.Println(len(menge), drin)
}3 true
Merke
- Arrays haben feste Länge; Slices (
[]T) wachsen mitappendund sind Sichten auf Arrays len,cap,copy,make; Teil-Slices teilen sich den Speicher- Maps:
m[k],v, ok := m[k],delete; Reihenfolge ist zufällig - Pakete
slicesundmaps(Go 1.21) bieten Sortieren, Suchen, Einfügen - Eine nil-Map nimmt keine Schreibzugriffe an: vorher
make
Aufgabe
Zähle, wie oft jeder Buchstabe in einem Text vorkommt, und gib die Buchstaben alphabetisch mit Anzahl aus.