Go Variadic Functions
A variadic function accepts any number of arguments for a single parameter. Instead of defining a fixed number of parameters, the function collects all extra arguments into a slice automatically. This is useful when the exact number of inputs is not known in advance.
Declaring a Variadic Function
Use three dots ... before the type of the last parameter to make it variadic.
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
fmt.Println(sum(1, 2)) // 3
fmt.Println(sum(10, 20, 30)) // 60
fmt.Println(sum(5, 5, 5, 5, 5)) // 25
}
Output:
3
60
25
How It Works Internally
sum(10, 20, 30)
│
▼
Go collects 10, 20, 30 into a slice: []int{10, 20, 30}
│
▼
Inside the function, numbers = []int{10, 20, 30}
The variadic parameter behaves like a regular slice inside the function body.
Variadic with Fixed Parameters
A function can have fixed parameters before the variadic one. The variadic parameter must always be last.
package main
import "fmt"
func greetAll(greeting string, names ...string) {
for _, name := range names {
fmt.Printf("%s, %s!\n", greeting, name)
}
}
func main() {
greetAll("Hello", "Alice", "Bob", "Charlie")
}
Output:
Hello, Alice!
Hello, Bob!
Hello, Charlie!
Passing a Slice to a Variadic Function
An existing slice is passed to a variadic function using the ... spread operator after the slice name.
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
scores := []int{10, 20, 30, 40}
fmt.Println(sum(scores...)) // 100
}
Variadic Function Diagram
func sum(numbers ...int) int
│
└── numbers is a []int slice inside the function
Calling:
sum(1, 2, 3) → numbers = []int{1, 2, 3}
sum(scores...) → numbers = scores (slice spread)
sum() → numbers = []int{} (empty — zero arguments is valid)
Empty Variadic Call
Calling a variadic function with zero arguments is perfectly valid. The parameter becomes an empty slice.
package main
import "fmt"
func printAll(items ...string) {
fmt.Println("Count:", len(items))
}
func main() {
printAll() // Count: 0
printAll("Go", "Python", "C") // Count: 3
}
Key Points
- Use
...typeto declare a variadic parameter — it must be the last parameter - Inside the function, the variadic parameter is a regular slice
- Pass a slice to a variadic function using the
...spread operator - Zero arguments is valid — the variadic parameter becomes an empty slice
- Go's built-in
fmt.Printlnis itself a variadic function
