Variadic functions in Golang

A variadic function is a function that accepts a varying number of arguments. To make the function variadic, we have to use an ellipsis ( … ) before the type of the last function parameter in the function declaration.

Syntax

func func_name( param1 param1_type, param2 ...param1_type){
  // code inside the function
}

The last parameter of the variadic function receives the variadic arguments as a slice, which can be further used by the function as a slice. A variadic function with only the variadic arguments can accept as many arguments as possible or as few as zero arguments.

Code example
package main

import (
	"fmt"
)

func print(ele ...int) {
	fmt.Println("elements passed to the function: ", ele)
}

func main() {
	print()
	print(12, 1, 44, 13)
	print(32, 11, 341, 41, 34)
}

Output –

elements passed to the function:  []
elements passed to the function:  [12 1 44 13]
elements passed to the function:  [32 11 341 41 34]

Here, if we haven’t provided any parameters, then it’s not an error, the function just receives an empty slice. The compiler tries to convert the variadic arguments received into the corresponding slice. So, in the above program, the compiler will try to do something like this :

func print([]int{ele})

So, we may visualize it as something like :

func print([]int{12, 1, 44, 13 })

which is essentially like creating a new slice and in this way, the variadic arguments received will be converted into a slice and thus can be used by the functions as such.

Let’s try out a variadic function with a combination of both non-variadic arguments and variadic arguments

Here, we will be making a variadic function having one normal argument ( non-variadic ) and a variadic argument. Here, we will have to pass at least one parameter for the normal argument, as we can only omit the variadic arguments but non-variadic arguments are always required.

package main

import (
	"fmt"
)

func print(num int, ele ...int) {

	fmt.Println("number passed is:", num, "and slice is:", ele)
}

func main() {
	print(1)
	print(12, 1, 44, 13)
	print(32, 11, 341, 41, 34)
}

Output –

number passed is: 1 and slice is: []
number passed is: 12 and slice is: [1 44 13]
number passed is: 32 and slice is: [11 341 41 34]

Here, we can see that the first parameter is mapped to the first argument of the function ( num ) and all of the other parameters are mapped with the variadic arguments and thus treated as a slice.

Variadic arguments should be the last one in a function definition

Here, we have to make sure of one thing that the variadic arguments should always be the last one in the function declaration. We cannot write non-variadic arguments after the variadic arguments in the function declaration, so, below kind of function declaration is not acceptable in the Go language.

func func_name(param1 ...int, param2 int){
 // code inside the function
}

We may also think of it as we have no way of knowing the param2 value here, as all of the parameters passed in the function should be assigned to param1 because it is variadic, and hence above function declaration will give you an error.

package main

import (
	"fmt"
)

func print(ele ...int, num int) {

	fmt.Println("number passed is:", num, "and slice is:", ele)
}

func main() {
	print(1)
	print(12, 1, 44, 13)
	print(32, 11, 341, 41, 34)
}

Output –

syntax error: cannot use ... with non-final parameter ele

Passing slices to variadic functions

Now, let’s try to pass a slice as a parameter into the variadic function and see what happens.

package main

import (
	"fmt"
)

func print(ele ...int) {

	fmt.Println("element passed in the function is: ", ele)
}

func main() {

	arrSlice := []int{12, 1, 44, 13}

	print(arrSlice)
}

Output –

 cannot use arrSlice (type []int) as type int in argument to print

So, here, we got a compilation error, this is because the variadic function again tries to change the arguments passed in the function to a slice by doing [ ]int{ele} but here the ele received is of type int[ ] and not int. So, it won’t be able to convert it into a slice and hence we got an error.

Now, to pass a slice into a variadic function, we need to add an ellipsis( … ) while passing a slice to the function.

print(arrSlice...)

Below is the revised program.

package main

import (
	"fmt"
)

func print(ele ...int) {

	fmt.Println("element passed in the function is: ", ele)
}

func main() {

	arrSlice := []int{12, 1, 44, 13}

	print(arrSlice...) // passing slice into the function
}

Output –

element passed in the function is:  [12 1 44 13]

Now, there is one point to note here is that when we pass a slice to a variadic function, then no new slice is created. So, if we modify the slice within the function then that change will be reflected outside of the function too.

Changing the passed slice within a variadic function

So, let’s try to change the slice passed into a variadic function and see whether the change is reflected outside of the function or not?

package main

import (
	"fmt"
)

func print(ele ...int) {
	ele[1] = 87 // changing the 2nd element value to 87
}

func main() {

	arrSlice := []int{12, 1, 44, 13}

	fmt.Println("Slice before passing into the function:", arrSlice)

	print(arrSlice...) // passing slice into the function

	fmt.Println("Slice after passing into the function:", arrSlice)
}

Output –

Slice before passing into the function: [12 1 44 13]
Slice after passing into the function: [12 87 44 13]

So, here we can see that the value is changed and reflected outside of the function too.

Hope you liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at [email protected]

Liked the article? Share this on

Leave a Comment

Your email address will not be published.