Content-Length: 135417 | pFad | https://medium.com/golangspec/variadic-functions-in-go-13c33182b851

Variadic functions in Go. Introduction for aspiring Gophers | by Michał Łowicki | golangspec | Medium
Sitemap
golangspec

A series dedicated to deeply understand Go’s specification and language’s nuances

Variadic functions in Go

Introduction for aspiring Gophers

3 min readOct 17, 2016

--

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

package mainimport "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 mainimport "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 mainimport "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/lab
value: []string{"one", "two", "three"}
type: []string
length: 3
capacity: 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 mainimport "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/lab
src/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 mainimport "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.

--

--

golangspec
golangspec

Published in golangspec

A series dedicated to deeply understand Go’s specification and language’s nuances

Michał Łowicki
Michał Łowicki

Written by Michał Łowicki

Software engineer at Datadog, previously at Facebook and Opera, never satisfied.

Responses (3)









ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://medium.com/golangspec/variadic-functions-in-go-13c33182b851

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy