Lo slice è un array dinamico, l'unità strutturale principale quando si lavora con gli array in Go. Storicamente, i linguaggi di programmazione offrivano array di dimensioni fisse o strutture più pesanti. Go ha implementato gli slice come uno strumento comodo per gestire collezioni di memoria con gestione automatica delle dimensioni e possibilità di modificare la lunghezza.
Il problema consiste nella corretta gestione della memoria, nella gestione dei casi limite (slice vuoti, nil, pieni) e nella comprensione della differenza tra lunghezza e capacità dello slice.
La soluzione è usare correttamente le funzioni incorporate len(), cap(), e operare sugli slice secondo le convenzioni di Go.
Esempio di codice:
var a []int // nil slice, len=0, cap=0 b := make([]int, 0) // slice vuoto, len=0, cap=0 c := make([]int, 3, 5) // len=3, cap=5 c = append(c, 4, 5, 6) // cap verrà aumentata automaticamente
Caratteristiche chiave:
var s []int) non alloca affatto memoria, si differenzia dallo slice vuoto (make([]int, 0)) solo internamente.Qual è la lunghezza e la capacità dello slice dopo append a un nil slice?
Nil slice (var s []int) dopo append(s, 1) diventa uno slice di lunghezza 1, capacità 1 — Go gestisce automaticamente l'allocazione.
var s []int s = append(s, 42) // s ora [42], len=1, cap=1
È possibile accedere alla capacity di uno slice pari a nil?
Sì, per il nil slice entrambe le funzioni — len e cap — restituiscono 0. Non ci sarà panico.
var s []int fmt.Println(len(s), cap(s)) // 0 0
Cosa succede se si prova a assegnare a un elemento per indice senza un’allocazione preventiva di memoria a uno slice pari a nil?
Panico index out of range, perché lo slice non ha elementi.
var s []int s[0] = 1 // panic: runtime error: index out of range
Il team ha deciso di utilizzare solo var s []T nel server Go, aspettandosi che fosse sempre equivalente a make([]T, 0). Di conseguenza, alcune serializzazioni JSON restituivano null anziché [].
Vantaggi:
Svantaggi:
Utilizzo di make([]T, 0, 100) per preallocazione, e successivamente solo append in un ciclo. In questo modo si minimizzano le allocazioni di memoria e si guadagna spesso in prestazioni.
Vantaggi:
Svantaggi: