Variadic-functies in Go stellen je in staat om een variabel aantal argumenten van hetzelfde type te accepteren dankzij de syntaxis met drie puntjes .... Bijvoorbeeld:
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
Je kunt zo'n functie aanroepen met een willekeurig aantal argumenten:
result := sum(1, 2, 3, 4) // 10
Of een slice doorgeven met behulp van de syntaxis ...:
numbers := []int{1,2,3} result := sum(numbers...) // 6
Fijnen:
[]T). Dit betekent dat je al een voorbereid slice kunt doorgeven.... doorgeeft, verwacht de functie een gewone parameter van het type []T, en geen variadic.Wat is het resultaat van de volgende code en waarom?
func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)
Veel mensen denken ten onrechte dat deze code zal compileren, maar in werkelijkheid zal deze een compilatiefout geven:
Fout: je kunt geen slice zonder ... doorgeven aan een variadic-parameter.
Correct:
printInts(ints...) // OK
Verhaal
In een groot project was de loggingfunctie beschreven als func Log(msgs ...string). Bij het doorgeven van een vooraf voorbereide slice van strings, werd gewoon Log(strings) aangeroepen, wat leidde tot een onjuiste loguitvoer of een panic tijdens het draaien. De reden was het ontbreken van ..., waardoor de functie één argument van het type []string als geheel beschouwde, in plaats van afzonderlijke strings.
Verhaal
In een van de hulpfuncties was het nodig om parameters te verwerken, waaronder een slice, en extra elementen aan deze slice toe te voegen. We verwachtten dat ... een kopie van de slice maakte, en niet een referentie doorgaf - maar binnen de functie wijzigden we de slice, wat onverwacht invloed had op de aanroepende kant, vooral als de oorspronkelijke slice een herbruikbare buffer was.
Verhaal
Een ontwikkelaar implementeerde aggregatiefuncties met behulp van een variadic-parameter, maar een van de collega’s gebruikte onjuist de aanroepsyntaxis via casting: sum(interface{}([]int)), wat leidde tot impliciete runtime-fouten, terwijl het correct zou zijn om expliciet sum(slice...) te gebruiken. Onbekendheid met de nuances veroorzaakte niet-evidente bugs tijdens massale refactoreringen.