In Go, le funzioni incorporate append, len e cap giocano un ruolo chiave nel lavoro con gli slice.
Esempio:
arr := []int{1,2,3} arr2 := append(arr, 4) // arr2 può essere nello stesso o in un nuovo backing array, a seconda di cap(arr)
Sottigliezze:
Cosa succederà se si "taglia" un pezzo dallo slice e si aggiunge un elemento tramite append? Questo influenzerà l'array originale?
Risposta: Se la cap lo consente, append scriverà l'elemento "in coda" all'array originale, e le modifiche saranno visibili attraverso tutti gli slice che fanno riferimento allo stesso array.
Esempio:
a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // cambia a: a -> [1, 2, 10, 4]
Storia
Nel team sono stati aggiunti elementi a uno slice figlio, e inaspettatamente sono stati modificati i dati nell'array padre — questo ha portato a disallineamenti nella logica aziendale e a bug difficili da debuggare nella distribuzione delle attività tra gli utenti.
Storia
Al secondo richiamo di append su uno slice grande, ci si aspettava che un nuovo array fosse sempre allocato nuovamente, ma di fatto diverse parti del sistema continuavano a lavorare con lo stesso "backing array", provocando una condizione di race e corruzione dei dati.
Storia
Uno sviluppatore ha allocato uno slice di dimensione fissa usando make, ma ha commesso un errore e ha scambiato gli argomenti: make([]int, cap, len). Di conseguenza, la logica basata sulla capacità ha inaspettatamente lavorato sulla lunghezza, causando panico quando si superavano i limiti s[0:len].