Golang variadic function Explained [Practical Examples]

What is the Variadic function in Go

A variadic function is one that can be called with varying numbers of arguments. The most familiar examples are fmt.Printf and its variants. Printf requires one fixed argument at the beginning, then accepts any number of subsequent arguments. It's just like other functions .

The parameter passed are stored in a slice of a specific data type. The last parameter is always followed by an ellipsis/unpack operator (...), which instructs Go to store all parameters of that type defined to be passed in the function.

Advertisement

 

Golang variadic function syntax

func functionName(param ...paramType){}

...paramType its a slice of arguments of paramType defined. i.e func fullName(name ...string)string {}, the function will accept parameter of type []string.
We use two mechanisms to interact with variadic functions namely:-

  • pack operator :- [...Type] It's used during defining variadic function because arguments are being added into the slice of array whenever passed in the function.
  • Unpack operator :- fmt.Println(param...) is used to retrieve content from the slice of the array.
NOTE:

You can't declare more params after a variadic params. i.e

func functionName(param ...paramType, param2 paramtype){}

It will always be an error.

 

Example of Variadic Function in Go

// main.go
package main

import (
	"fmt"
	"os"
	"strings"
)

func JoinString(separator string, data ...string) string {
	var str string
	if !(len(data) < 1) {
		for i, v := range data {
			str = str + v
			if i != len(data)-1 {
				str = str + separator
			}
		}
		return str
	}
	return fmt.Sprintf("No elements passed %v", str)

}

func main() {
	dataInput := os.Args[1:]
	fmt.Printf("Results : %s", JoinString(",", dataInput...))
}

Output:- 1 With arguments provided

Advertisement
$go run main.go GoLinuxCloud AWS Google Azure
Results : GoLinuxCloud,AWS,Google,Azure

Output:- 2 Without arguments provided

$go run main.go                               
Results : No elements passed

Explanation:-

Our variadic function is func JoinString(separator string, data ...string) string {} it accepts separator and list of data might be names of teams or other items. pack operator is used at [data ...string] while unpack operator is used during printing the output fmt.Printf("Results : %s", JoinString(separator, dataInputs...)) [dataInputs...] is unpack operator which enable us to access values in a slice without creating a slice array and we don't have to use inbuilt append(slice,data..) function to update our slice.

 

Method :-1 Example of built-in variadic function in Go

In the Go Standard library Printf function from fmt package, which accepts different data types at once, since it uses interface type. The interface allows us to pass unknown data types and numerous arguments. func Printf(format string, a ...interface{})

For example fmt.Printf()

// main.go
package main

import "fmt"

func main() {
	var name string
	var age int64
	var salary float64
	fmt.Print("Enter your firstName: \n ")
	fmt.Scanf("%s", &name)
	fmt.Print("Enter your age: \t ")
	fmt.Scanf("%v", &age)

	fmt.Print("Enter your hourly rate : \t ")
	fmt.Scanf("%f", &salary)

	// variadic function
	fmt.Printf("My name is  %s, %v years of age ,and hourly rate of $ %.2f  salary.", name, age, salary)
}

Output:-

$go run main.go
Enter your firstName: 
 Doe
Enter your age:          
30
Enter your hourly rate :      
50
My name is  Doe, 30 years of age, and hourly rate of $ 50.00  salary.

Explanation :-

We execute our main()function which let you enter several variable, we read those variable using fmt.Scanf() function from fmt package, we store the entered value into our variables name,age,salary.

We print out the expected output using fmt.Printf() function which accepts various arguments of different types as seen above.

 

Method :-2 Passing slice elements in Go variadic function

A slice is an array of unknown lengths, which can be manipulated by adding more elements. Using variadic function we can manipulate slice using append(slice,element...) syntax.

 

Example: Adding elements in a slice

package main

import (
	"fmt"
)

func sumIntegers(elem ...int64) int64 {
	var sum int64
	for i := range elem {
		sum += elem[i]
	}
	return sum
}
func main() {
	data := []int64{2, 4, 5, 7, 8}
	sum := sumIntegers(data...)
	fmt.Printf("Elements are %v and total is %v", data, sum)

}

Output

$ go run main.go
Elements are [2 4 5 7 8] and total is 26

Explanation :-

In the above we can unpack elements of a slicedata := []int64{2, 4, 5, 7, 8} directly to a variadic function func sumIntegers(elem ...int64) int64 {}using the data... unpacking to function. Under the hood data... creates a new slice and works well.

Advertisement

 

Example: Manipulating slice using variadic function

package main

import (
	"fmt"
)

func product(num int64, elem ...int64) []int64 {
	for key, val := range elem {
		elem[key] = num * val
	}
	return elem
}
func main() {
	data := []int64{2, 4, 5, 7, 8}
	originalData := fmt.Sprintf("%v", data)
	prod := product(3, data...)
	fmt.Printf("Elements are %v and product is %v", originalData, prod)
}

Output

$ go run main.go
Elements are [2 4 5 7 8] and product is [6 12 15 21 24]

Explanation:-

In the above code, unpack(...) operator is our main focus, instead of creating a slice to append those elements into it, Go underhood, creates a new slice that holds every change.

 

Method:-3 Passing non variadic parameters and mixing variadic

The variadic function accepts numerous parameters thus mixing non-variadic arguments i.e num int64 with variadic arguments/param str ...string by putting the non variadic arguments before the variadic params i.e func functionName(param type, param2 ...param2Type) returnType{}.

Example

Advertisement
// main.go
package main

import (
	"fmt"
	"os"
	"strconv"
	"strings"
)

func MixVariadic(age int64, salary float64, name ...string) string {
	return fmt.Sprintf("My name is  %s, %02d years of age ,and my hourly rate is $ %.2f.\n", strings.Join(name, " "), age, salary)
}

func main() {
	age, _ := strconv.ParseInt(os.Args[1], 10, 64)
	salary, _ := strconv.ParseFloat(os.Args[2], 64)
	name := os.Args[3:]
	fmt.Printf("Results : %s", MixVariadic(age, salary, name...))
}

Output

$ go run main.go 28 50 John Doe
Results: My name is  John Doe, 28 years of age, and my hourly rate is $ 50.00.

Explanation:-

func MixVariadic(age int64, salary float64, name ...string) string {} this is an example of mixed variadic and non variadic params. we have used the os package to read values from the terminal while executing our function and strconv package to convert the input params into our defined data type.

 

Summary

In this article, we have learned that Variadic functions are essential when passing numerous numbers of unknown params, increasing the readability of the function and holding a temporary slice of variable which can be passed into a function without declaring it.

 

Reference

variadic function

 

Related Keywords: variadic function golang, pass array to variadic function golang, golang variadic function interface, golang variadic function different types, pass variadic arguments to another function golang, golang mock variadic function, golang function return variadic, golang reflect variadic function, golang variadic function documentation, golang pass slice to variadic function, golang variadic function array, golang variadic function different types, golang multiple variadic arguments, golang variadic slice, golang variadic options

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X