Variadic Functions

Let’s learn about variadic functions.

Variadic functions are functions that can accept a variable number of parameters—we already know about fmt.Println() and append(), which are both variadic functions that are widely used. In fact, most functions found in the fmt package are variadic.

General ideas and rules

The general ideas and rules behind variadic functions are as follows:

  • Variadic functions use the pack operator, which consists of a ..., followed by a data type. So, for a variadic function to accept a variable number of int values, the pack operator should be ...int.

  • The pack operator can only be used once in any given function.

  • The variable that holds the pack operation is a slice and, therefore, is accessed as a slice inside the variadic function.

  • The variable name that is related to the pack operator is always last in the list of function parameters.

  • When calling a variadic function, we should put a list of values separated by , in the place of the variable with the pack operator or a slice with the unpack operatorThe unpack operator unpacks the content of the slice..

This list contains all the rules that we need to know in order to define and use variadic functions.

Note: The pack operator can also be used with an empty interface. In fact, most functions in the fmt package use ...interface{} to accept a variable number of arguments of all data types.

The source code of the latest implementation of fmt can be accessed online.

Passing os.Args as ...interface{}

However, there is a situation that needs special care here. If we try to pass os.Args, which is a slice of strings ([]string), as ...interface{} to a variadic function, our code will not compile and will generate an error message similar to cannot use os.Args (type []string) as type []interface {} in argument to <function_name>. This happens because the two data types ([]string and []interface{}) do not have the same representations in memory—this applies to all data types. In practice, this means that we can’t use os.Args... to pass each individual value of the os.Args slice to a variadic function.

On the other hand, if we just use os.Args, it will work, but this passes the entire slice as a single entity instead of passing its individual values! This means that the everything(os.Args, os.Args) statement works but does not do what we want.

The solution to this problem is converting the slice of strings—or any other slice—into a slice of interface{}. One way to do that is by using the code that follows:

Get hands-on with 1200+ tech skills courses.