Sobes.tech
Junior

Come funzionano gli slice in Go?

sobes.tech AI

Risposta dell'AI

Uno slice è un involucro leggero sopra un array. Non memorizza i dati da solo, ma fa riferimento a un array di base.

Struttura dello slice:

  • Puntatore all'array di base: Indirizzo del primo elemento dello slice in memoria.
  • Lunghezza (Length): Numero di elementi nello slice.
  • Capacità (Capacity): Numero di elementi nell'array di base, disponibili a partire dal puntatore dello slice.
// Esempio di dichiarazione di uno slice
var s []int
s = append(s, 1, 2, 3) // Aggiunta di elementi

// Rappresentazione interna di s (semplificata)
// struct SliceHeader {
//     Data uintptr // Puntatore all'array di base
//     Len int      // Lunghezza dello slice
//     Cap int      // Capacità dello slice
// }
  • Creando uno slice con make([]T, length, capacity) si crea un array di base con la capacità specificata e uno slice che vi fa riferimento con la lunghezza indicata.
  • Usando una fetta su un array o un altro slice (ad esempio, arr[low:high:max]), si crea un nuovo slice che fa riferimento alla stessa area di memoria dell'array di base, ma con puntatori, lunghezza e capacità differenti.
  • L'operazione append può provocare una riallocazione della memoria. Se la capacità attuale non è sufficiente per aggiungere nuovi elementi, Go crea un nuovo array di base più grande, copia gli elementi vecchi e aggiorna il puntatore dello slice al nuovo array. Questo si chiama reallocation. La crescita della capacità durante l'append è esponenziale (raddoppia fino a una certa dimensione, poi rallenta).
  • Gli slice vengono passati per valore, ma poiché contengono un puntatore all'array di base, le modifiche agli elementi dello slice (tramite indice) saranno visibili in tutti gli slice che fanno riferimento allo stesso array.
  • Modificare la lunghezza dello slice tramite slicing non influisce sull'array di base, ma può limitare l'accesso a parte dei dati dell'array di base.

Tabella: Confronto tra Length e Capacity

Caratteristica Lunghezza (Length) Capacità (Capacity)
Definizione Numero reale di elementi nello slice Numero massimo di elementi che lo slice può contenere senza reallocation
Accesso Usato per accedere agli elementi (s[i]) Determina quanti altri elementi possono essere aggiunti con append prima della reallocation
Ottenimento len(s) cap(s)
// Esempio di lavoro con capacità e lunghezza
s := make([]int, 0, 5) // Lunghezza 0, capacità 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // Aggiunta di 2 elementi
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // Aggiunta di altri 4 elementi, necessita di reallocation
fmt.Println(len(s), cap(s)) // 6 10 (la capacità è aumentata)