## Introduction for aspiring Gophers

Function is variadic if and only if the last parameter is of type …T (three dots before T are not there by accident):

`package main`
`import "fmt"`
`func sum(numbers ...float64) (res float64) {    for _, number := range numbers {        res += number    }    return}`
`func main() {    fmt.Println(sum(1.1, 2.2, 3.3))}`

It allows to pass arbitrary (variable) number of arguments. They’re available inside function through elements of a slice (numbers parameter in code above).

Only the last parameter can be preceded with … (three dots) denoting variadic function.

#### argument vs. parameter

Most of the time these terms can be used interchangeably but arguments usually refer to actual values in function / method call and parameters are specified in function declaration:

`package main`
`import "fmt"`
`func sum(a, b float64) (res float64) {    return a + b}`
`func main() {    fmt.Println(sum(1.1, 1.2))}`
• a and b are parameters
• res is a named result parameter
• 1.1 and 1.2 are arguments

#### … becomes a slice

The actual type of …T inside the function is []T:

`package main`
`import "fmt"`
`func f(names ...string) {    fmt.Printf("value: %#v\n", names)    fmt.Printf("length: %d\n", len(names))    fmt.Printf("capacity: %d\n", cap(names))    fmt.Printf("type: %T\n", names)}`
`func main() {    f("one", "two", "three")}`

The compiled code produces:

`> go install github.com/mlowicki/lab && ./bin/labvalue: []string{"one", "two", "three"}type: []stringlength: 3capacity: 3`

#### Type identity

Type of variadic function isn’t equal to the one which takes slice as a last parameter:

`f := func(...int) {}f = func([]int) {}`

It’s detected while building:

`src/github.com/mlowicki/lab/lab.go:17: cannot use func literal (type func([]int)) as type func(...int) in assignment`

#### Let’s put dots on the other side…

Next snippet cannot be compiled successfully:

`package main`
`import "fmt"`
`func f(numbers ...int) {    fmt.Println(numbers)}`
`func main() {    numbers := []int{1, 2, 3}    f(numbers)}`
`> go install github.com/mlowicki/lab && ./bin/lab# github.com/mlowicki/labsrc/github.com/mlowicki/lab/lab.go:11: cannot use numbers (type []int) as type int in argument to f`

It’s because a single argument needs to have a int type so slice of integers is obviously not allowed. There is a mechanism directly in the language to make it working:

`package main`
`import "fmt"`
`func f(numbers ...int) {    fmt.Println(numbers)}`
`func main() {    numbers := []int{1, 2, 3}    f(numbers...)}`

The change which is easily to overlook are three dots (…) after the argument in call to function f. It passes numbers as a list of arguments. This way it’s possible to call variadic function passing slice of elements.

Variadic functions are syntactic sugar for functions taking slice as a last parameter. They can be used to design more expressive APIs and release programmer from creating temporary slices.

If you like the post and want to get updates about new ones please follow me. Help also others discover this story by clicking ❤ below.