Variadic functions in Go allow you to take a variable number of arguments of the same type using the ellipsis syntax .... For example:
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
You can call such a function with any number of arguments:
result := sum(1, 2, 3, 4) // 10
Or pass a slice using the ... syntax:
numbers := []int{1,2,3} result := sum(numbers...) // 6
Nuances:
[]T). This means you can pass a pre-prepared slice...., the function expects a regular parameter of type []T, not variadic.What result will the following code give and why?
func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)
Many mistakenly believe that this code will compile, but it will actually result in a compilation error:
Error: cannot pass a slice without ... to a variadic parameter.
Correct:
printInts(ints...) // OK
Story
In a large project, a logging function was defined as func Log(msgs ...string). When passing a pre-prepared slice of strings, they simply called Log(strings) and received incorrect log output or a panic during execution. The reason was the absence of ..., causing the function to perceive a single argument of type []string, not separate strings.
Story
In one of the utility functions, it was necessary to process parameters, including a slice, and add more elements to it inside. They expected that ... would create a copy of the slice, not pass a reference — but inside the function, they modified the slice, which unexpectedly affected the caller, especially if the original slice was a reusable buffer.
Story
A developer implemented aggregation functions using a variadic parameter, but one of his colleagues incorrectly used the call syntax via casting: sum(interface{}([]int)), leading to implicit runtime errors, while it should have been explicitly sum(slice...). Ignorance of the nuances caused non-obvious bugs during massive refactorings.