Lezioni del modulo (2/5)
Slice: la struttura idiomatica
Una slice è la struttura dati più usata in Go: una vista
dinamica su un array sottostante. Sintassi: []T. A differenza
degli array, la lunghezza non fa parte del tipo, e puoi farla crescere
con append.
Anatomia di una slice
Internamente una slice è una struttura a tre campi:
- un puntatore al primo elemento nell'array sottostante
- una lunghezza (
len): numero di elementi visibili - una capacità (
cap): elementi disponibili dall'inizio della vista fino alla fine dell'array sottostante
s := []int{10, 20, 30}
fmt.Println(len(s), cap(s)) // 3 3Creazione
a := []int{1, 2, 3} // letterale
b := make([]int, 3) // [0 0 0] len=3 cap=3
c := make([]int, 3, 10) // len=3 cap=10 (riservata)
var d []int // nil slice: len=0 cap=0, ma usabile con appendappend: assegna sempre il risultato
append aggiunge elementi e ritorna una nuova slice (potenzialmente
allocando un nuovo array se la capacità non basta):
s := []int{1, 2, 3}
s = append(s, 4) // [1 2 3 4]
s = append(s, 5, 6, 7) // aggiungi più elementi
s = append(s, altra...) // concatena un'altra slice (spread)Slice expression s[a:b]
Estrae una sottoslice da a (incluso) a b (escluso):
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]Le sottoslice condividono l'array sottostante con la slice
originale: modifiche in sub[i] = ... sono visibili anche in s.
Pitfall: condivisione dell'array
s := []int{1, 2, 3, 4}
sub := s[0:2]
sub[0] = 99
fmt.Println(s) // [99 2 3 4] — modificato!Per ottenere una copia indipendente usa copy o append:
out := make([]int, len(sub))
copy(out, sub)Prova tu
Crea uno slice s con [1, 2, 3] e usa append per aggiungere 4.
Mostra suggerimento
Assegna SEMPRE il risultato di append a `s`.
Soluzione disponibile dopo 3 tentativi
Estrai con uno slice expression gli elementi dall'indice 1 incluso al 3 escluso (cioè [20, 30]).
Mostra suggerimento
Sintassi: `s[inizio:fine]`, `inizio` incluso, `fine` escluso.
Soluzione disponibile dopo 3 tentativi
Quale di queste è SBAGLIATO scrivere?
s := []int{1, 2, 3}
// (a) s = append(s, 4)
// (b) append(s, 4)Recap
[]T: vista dinamica su un array; tripla (ptr, len, cap).make([]T, len, cap)per pre-allocare;var s []Tper nil slice usabile.s = append(s, ...): assegna SEMPRE il risultato.s[a:b]condivide l'array sottostante:copy(...)per copie indipendenti.nilslice = OK per leggere/range/append; ben diversa da una nil map.