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 ...type to 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.Println is itself a variadic function

Leave a Comment