Les fonctions variadiques en Go permettent de prendre un nombre variable d'arguments d'un type donné grâce à la syntaxe avec trois points .... Par exemple:
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
Cette fonction peut être appelée avec n'importe quel nombre d'arguments:
result := sum(1, 2, 3, 4) // 10
Ou transmettre une tranche en utilisant la syntaxe ...:
numbers := []int{1,2,3} result := sum(numbers...) // 6
Subtilités:
[]T). Cela signifie que vous pouvez passer une tranche préparée...., la fonction attend un paramètre normal de type []T, et non variadique.Quel résultat donnera le code suivant et pourquoi ?
func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)
Beaucoup pensent à tort que ce code se compilera, mais en réalité il provoquera une erreur de compilation:
Erreur : impossible de passer une tranche sans ... à un paramètre variadique.
Correct :
printInts(ints...) // OK
Histoire
Dans un grand projet, la fonction de journalisation était décrite comme func Log(msgs ...string). Lors du passage d'une tranche de chaînes préparée, on appelait simplement Log(strings), ce qui produisait une sortie de journal incorrecte ou un panic pendant l'exécution. La raison en était l'absence de ..., donc la fonction interprétait un argument de type []string, et non des chaînes individuelles.
Histoire
Dans une des fonctions utilitaires, il était nécessaire de traiter des paramètres, parmi lesquels se trouvait une tranche, et d'y ajouter davantage d'éléments à l'intérieur. On pensait que ... créait une copie de la tranche, et non passait une référence — mais à l'intérieur de la fonction, la tranche était modifiée, ce qui affectait de manière inattendue la partie appelante, surtout si la tranche d'origine était un tampon réutilisable.
Histoire
Un développeur a réalisé des fonctions d'agrégation en utilisant un paramètre variadique, mais un des collègues a mal utilisé la syntaxe d'appel via un casting : sum(interface{}([]int)), ce qui entraînait des erreurs d'exécution implicites, alors qu'il aurait été correct d'utiliser explicitement sum(slice...). L'ignorance des nuances a causé des bogues non évidents lors de refactorisations massives.