ProgrammatieBackend ontwikkelaar

Beschrijf hoe variadic functies (functies met een variabel aantal argumenten) in Go zijn geïmplementeerd. Hoe moet je ze correct declareren, aanroepen en welke valkuilen kunnen er zijn bij het doorgeven van slices?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

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:

  • Binnen de functie worden variadic-parameters gezien als een slice ([]T). Dit betekent dat je al een voorbereid slice kunt doorgeven.
  • Dergelijke parameters moeten altijd de laatste in de parameterlijst van de functie zijn.
  • Als je een slice zonder ... doorgeeft, verwacht de functie een gewone parameter van het type []T, en geen variadic.

Vraag met een valstrik

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

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp


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.