ProgrammazioneSviluppatore Backend

Descrivi come sono implementate le funzioni variadic (funzioni con un numero variabile di argomenti) in Go. Come devono essere dichiarate, chiamate e quali insidie ci possono essere nella trasmissione di slice?

Supera i colloqui con l'assistente IA Hintsage

Risposta

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à:

  • Nei parametri variadic, i parametri appaiono come uno slice ([]T). Questo significa che è possibile passare uno slice già preparato.
  • Tali parametri devono sempre essere gli ultimi nell'elenco dei parametri della funzione.
  • Se si passa uno slice senza ..., la funzione si aspetta un parametro normale di tipo []T, e non variadic.

Domanda ingannevole

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

Esempi di errori reali a causa della mancanza di conoscenza delle particolarità dell'argomento


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.