In Go, la struttura map viene sempre passata per valore, ma questo valore contiene un puntatore alle strutture interne della mappa stessa (sottoposta all'hash-table). Quindi, se si passa una mappa a una funzione e all'interno della funzione si modifica il contenuto (si aggiungono/rimuovono elementi), le modifiche saranno visibili all'esterno. Comportamenti simili hanno anche gli slice: viene copiata la struttura dello slice, ma non i dati dell'array; lo slice contiene un puntatore all'array, la lunghezza e la capacità. Se si modificano i valori per indice all'interno della funzione, anche l'array originale cambierà. Ma se all'interno della funzione si assegna un nuovo slice (ad esempio, reslice), la variabile originale non cambierà.
func updateMap(m map[string]int) { m["key"] = 42 // Le modifiche sono visibili all'esterno! } func updateSlice(s []int) { s[0] = 99 // L'array originale cambia }
Perché la modifica di mappe e slice all'interno di una funzione si riflette sull'"originale"?
Risposta: Perché viene copiata solo la struttura del puntatore, mentre i dati stessi rimangono condivisi: qualsiasi modifica coinvolge lo stesso blocco di memoria.
Storia
In un progetto fintech, si passava una mappa con impostazioni di configurazione a diversi servizi, supponendo che le modifiche locali non avrebbero influenzato la mappa generale. Di conseguenza, un servizio ha modificato i valori, causando bug in altri moduli che hanno ricevuto una configurazione inaspettatamente modificata.
Storia
In un microservizio di analisi, si passava uno slice, pensando di ottenere copie indipendenti. Ma la funzione all'interno ha modificato i valori per indice, portando a dati distorti nel rapporto, poiché l'array originale è stato inaspettatamente modificato.
Storia
Nei server di gioco, si utilizzava una mappa per memorizzare le sessioni degli utenti e si passava contemporaneamente questa mappa a più goroutine. Si pensava che ogni goroutine lavorasse con la propria copia, ma in realtà si è verificata una race condition e sessioni parzialmente perse.