ProgrammierungBackend Entwickler

Beschreiben Sie, wie variadische Funktionen (Funktionen mit variabler Argumentanzahl) in Go implementiert sind. Wie werden sie korrekt deklariert, aufgerufen, und welche Fallstricke können beim Übergeben von Slices auftreten?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

Variadic-Funktionen in Go ermöglichen es, eine variable Anzahl von Argumenten desselben Typs durch die Syntax mit Auslassungszeichen ... zu akzeptieren. Zum Beispiel:

func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }

Eine solche Funktion kann mit beliebig vielen Argumenten aufgerufen werden:

result := sum(1, 2, 3, 4) // 10

Oder man kann ein Slice mit der Syntax ... übergeben:

numbers := []int{1,2,3} result := sum(numbers...) // 6

Feinheiten:

  • In der Funktion sind variadic-Parameter als Slice sichtbar ([]T). Das bedeutet, dass man bereits ein vorbereitetes Slice hinein übergeben kann.
  • Solche Parameter müssen immer die letzten in der Parameterliste der Funktion sein.
  • Wenn ein Slice ohne ... übergeben wird, erwartet die Funktion einen normalen Parameter vom Typ []T und nicht variadic.

Trickfrage

Welches Ergebnis liefert der folgende Code und warum?

func printInts(nums ...int) { fmt.Printf("%#v\n", nums) } ints := []int{1, 2, 3} printInts(ints)

Viele glauben fälschlicherweise, dass dieser Code kompiliert, aber tatsächlich wird er einen Kompilierungsfehler verursachen:

Fehler: Es ist nicht möglich, ein Slice ohne ... an einem variadic Parameter zu übergeben.

Richtig:

printInts(ints...) // OK

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas


Geschichte

In einem großen Projekt wurde die Logging-Funktion als func Log(msgs ...string) beschrieben. Bei der Übergabe eines bereits vorbereiteten Slices von Strings wurde einfach Log(strings) aufgerufen, was zu falschen Logausgaben oder Panic zur Laufzeit führte. Der Grund dafür war das Fehlen von ..., sodass die Funktion einen einzelnen Parameter vom Typ []string anstatt separater Strings verstand.


Geschichte

In einer der Hilfsfunktionen war es erforderlich, Parameter zu verarbeiten, darunter ein Slice, und weitere Elemente hinzuzufügen. Man erwartete, dass ... eine Kopie des Slices erstellt, anstatt einen Verweis zu übergeben – aber innerhalb der Funktion wurde das Slice verändert, was unerwartet Einfluss auf die aufrufende Seite hatte, insbesondere wenn das ursprüngliche Slice ein wiederverwendeter Puffer war.


Geschichte

Ein Entwickler implementierte Aggregationsfunktionen, indem er einen variadic Parameter verwendete, aber einer der Kollegen verwendete fälschlicherweise die Aufrufsyntax durch Casting: sum(interface{}([]int)), was zu offensichtlichen Laufzeitfehlern führte, während es korrekt gewesen wäre, explizit sum(slice...) zu verwenden. Unkenntnis der Nuancen führte zu unerwarteten Bugs bei umfangreichen Refactorings.