## What is a variadic function?

As we have seen in a `functions` lesson, a function is a piece of code dedicated to do a particular job. A function takes one or many arguments and may return one or many values. Variadic functions are also functions but they can take an infinite or variable number of arguments. Sounds stupid but we have seen this in `slices` lesson when `append` function accepted a variable number of arguments.

`func f(elem ...Type)`

A typical syntax of a variadic function looks like above. `...` operator called as pack operator instructs go to store all arguments of type `Type` in `elem` parameter. With this syntax, go creates `elem` variable of the type `[]Type` which is a slice. Hence, all arguments passed to this function is stored in a `elem` slice.

Let’s take an example of `append` function.

`append([]Type, args, arg2, argsN)`

`append` function expects the first argument to be a `slice` of type `Type`, while there can be a variable number of arguments after that. If we have a slice `s2` that we want to append to a slice `s1`, how that will work?

As from `append` function syntax, we can’t pass another slice as an argument, it has to be one or many arguments of type `Type`. Hence, instead, we will use the unpack operator `...` to unpack slice into the series of arguments (which is acceptable by `append` function).

`append(s1, s2...)`

`...` signifies both `pack` and `unpack` operator but if three dots are in the tail position, it will unpack a slice.

Here `s1` and `s2` are two slices of the same type. Usually, we know function parameters and how many arguments a function can accept. Then how `append` function knows how many parameters has passed to it?

If you look at the signature `append` function,

`func append(slice []Type, elems ...Type) []Type`

You will see `elems ...Type` which means pack all incoming arguments into `elems` slice after the first argument.

One important thing to notice is that only the last argument of a function is allowed to be variadic.

So the first argument to `append` function will be a slice because it demands a slice but later arguments will be packed into one argument `elems`. I hope that makes it clear and now let’s look at creating your own `variadic` function.

## ☛ How to create a variadic function?

As discussed earlier, variadic function nothing but a function that accepts a variable number of arguments. To make a function accept a variable number of arguments, we need to use `pack` operator `...Type`.

unpack operator ends with `...` like `slice...` while pack operator starts with `...` like `...Type`.

Let’s write `getMultiples` function whose first argument is `factor` of type `int` which is a factor of multiplication and later variable arguments (hence variadic arguments) of type `int` are packed into the slice `args`.

In this function, we are creating an empty slice using `make` function with length equal to the length of `args` which is a slice. Using `for range`, we are multiplying `factor` with elements of `args` and saving them in `multiples`. Later, we return the slice `multiples`.

`func getMultiples(factor int, args ...int) []int {	multiples := make([]int, len(args))	for index, val := range args {		multiples[index] = val * factor	}	return multiples}`

This is as simple as it can get. We can implement this function inside `main` function like

`func main() {	s := []int{10, 20, 30}	mult1 := getMultiples(2, s...)	mult2 := getMultiples(3, 1, 2, 3, 4)	fmt.Println(mult1)	fmt.Println(mult2)}`

What will happen if in above example, you pass slice `s` directly to `getMultiples` function as second argument. Obviously, compiler will complain `cannot use s (type []int) as type int in argument to getMultiples` because slice is type of `[]int` and `getMultiples` expects parameter(s) of `int`.

## ☛ How `slice` is passed to a variadic function?

A slice is a reference to an array, what happens when you pass a slice to a variadic function using `unpack` operator. Does go creates a new slice `args` or keeps the same slice `s`. Since, we don’t have any tool to compare, `args == s`, we need to mutate `args` slice itself to check if the original slice `s` mutated.

In the above program, we have modified `getMultiples` variadic function slightly and instead of creating a new slice, we assigned multiplication values to `args` itself replacing incoming elements with multiplied elements.

From the above result, we can see values of slice `s` changed. This means, go in case of `slice` when passed to a variadic function using `unpack` operator, will use underneath array to build new slice. So, be careful.

Written by

## Uday Hiwarale

#### A place to find introductory Go Programming Language tutorials and learning resources. Like my other tutorials on Web Development, Run Go publication features important Go articles with deep dive into core of the language with examples and sample code.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just \$5/month. Upgrade