Le funzioni variadic in Go consentono di accettare un numero variabile di argomenti dello stesso tipo grazie alla sintassi con i puntini di sospensione .... Ad esempio:
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
È possibile chiamare questa funzione con qualsiasi numero di argomenti:
result := sum(1, 2, 3, 4) // 10
Oppure passare uno slice utilizzando la sintassi ...:
numbers := []int{1,2,3} result := sum(numbers...) // 6
Particolarità:
[]T). Questo significa che è possibile passare uno slice già preparato...., la funzione si aspetta un parametro normale di tipo []T, e non variadic.Qual è il risultato del seguente codice e perché?
func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)
Molti erroneamente pensano che questo codice si compili, ma in realtà genererà un errore di compilazione:
Errore: non puoi passare uno slice senza ... a un parametro variadic.
Corretto:
printInts(ints...) // OK
Storia
In un grande progetto, la funzione di logging è stata descritta come func Log(msgs ...string). Quando si passava uno slice di stringhe già preparato, si chiamava semplicemente Log(strings), ottenendo un'uscita di log errata o panic durante l'esecuzione. La causa era l'assenza di ..., quindi la funzione interpretava un singolo argomento di tipo []string invece di stringhe separate.
Storia
In una delle funzioni utility era necessario elaborare parametri, tra i quali c'era uno slice, e aggiungere ulteriori elementi al suo interno. Si pensava che ... creasse una copia dello slice, e non passasse un riferimento, ma all'interno della funzione lo slice veniva modificato, influenzando inaspettatamente la parte chiamante, specialmente se lo slice originale era un buffer riutilizzabile.
Storia
Uno sviluppatore ha implementato funzioni di aggregazione utilizzando parametri variadic, ma un collega ha utilizzato erroneamente la sintassi di chiamata attraverso il casting: sum(interface{}([]int)), il che portava a errori di runtime impliciti, mentre sarebbe stato corretto usare esplicitamente sum(slice...). La mancanza di conoscenza delle sfumature causava bug non evidenti durante massicci refactoring.