Modulelessen (2/5)
Slices: de idiomatische structuur
Een slice is de meest gebruikte gegevensstructuur in Go: een dynamische weergave
over een onderliggende array. Syntaxis: []T. In tegenstelling tot arrays is de lengte
maakt geen deel uit van het type en je kunt het laten groeien met append.
Anatomie van een plakje
Intern is een slice een structuur met drie velden:
- een pointer naar het eerste element in de onderliggende array
- a lengte (
len): aantal zichtbare elementen - een capaciteit (
cap): elementen beschikbaar vanaf het begin van de weergave naar het einde van de onderliggende array
s := []int{10, 20, 30}
fmt.Println(len(s), cap(s)) // 3 3Creatie
a := []int{1, 2, 3} // literal
b := make([]int, 3) // [0 0 0] len=3 cap=3
c := make([]int, 3, 10) // len=3 cap=10 (reserved)
var d []int // nil slice: len=0 cap=0, still usable with appendappend: wijs altijd het resultaat toe
append voegt elementen toe en retourneert een nieuw segment (mogelijk
een nieuwe array toewijzen als de capaciteit onvoldoende is):
s := []int{1, 2, 3}
s = append(s, 4) // [1 2 3 4]
s = append(s, 5, 6, 7) // append multiple elements
s = append(s, altra...) // concatenate another slice (spread)Segmentexpressie s[a:b]
Extraheert een subsegment van a (inclusief) tot b (exclusief):
s := []int{10, 20, 30, 40, 50}
sub := s[1:4] // [20 30 40]
inizio := s[:2] // [10 20]
fine := s[3:] // [40 50]
intera := s[:] // [10 20 30 40 50]Subsegmenten delen de onderliggende array met het originele segment:
mutaties via sub[i] = ... zijn ook zichtbaar in s.
Valkuil: het delen van arrays
s := []int{1, 2, 3, 4}
sub := s[0:2]
sub[0] = 99
fmt.Println(s) // [99 2 3 4] — modified!Gebruik copy of append om een onafhankelijke kopie te krijgen:
out := make([]int, len(sub))
copy(out, sub)Probeer het
Maak een segment s met [1, 2, 3] en gebruik append om 4 toe te voegen.
Toon hint
Wijs het resultaat van append ALTIJD toe aan `s`.
Oplossing beschikbaar na 3 pogingen
Gebruik een segmentexpressie om elementen te extraheren uit index 1 inclusief tot en met 3 exclusief (d.w.z. [20, 30]).
Toon hint
Syntaxis: `s[start:eind]`, `start` inclusief, `end` exclusief.
Oplossing beschikbaar na 3 pogingen
Welke van deze is VERKEERD om te schrijven?
s := []int{1, 2, 3}
// (a) s = append(s, 4)
// (b) append(s, 4)Samenvatten
[]T: dynamische weergave van een array; drievoudig (ptr, len, cap).make([]T, len, cap)om vooraf toe te wijzen;var s []Tvoor een bruikbaar nulsegment.s = append(s, ...): wijs ALTIJD het resultaat toe.s[a:b]deelt de onderliggende array:copy(...)voor onafhankelijke kopieën.- Een
nilsegment = OK om te lezen/bereiken/toevoegen; heel anders dan een nulkaart.