Passing slices to variadic functions

December 27, 2023

Passing arguments to ... parameters

If the final argument is assignable to a slice type []T and is followed by ..., it is passed unchanged as the value for a ...T parameter. In this case no new slice is created.

Given the slice s and call

s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)

within Greeting, who will have the same value as s with the same underlying array.

This leads to a few gotchas that I’ll spend today talking about.

The first, and probably most annoying, is that you cannot mix the s... syntax with other arguments. In other words, the following is invalid:

kids := []string{"James", "Jasmine"}
Greeting("goodbye", "Mom", "Dad", kids...)

You can either provide individual arguments or a slice, not both. This leads to the rather cumbersome, but functional, alternative:

Greeting("goodbye", append([]string{"Mom", "Dad"}, kids...)...)

The second gotcha can bite you when working with slices of interfaces, particularly empty interfaces, though in principle it could happen with others. The gotcha is that it can be easy to forget the ... suffix, and end up doing something you don’t intend. Let’s first examine a simple example involving fmt.Println, then I’ll discuss what’s going on:

kids := []any{"James", "Jasmine"}
fmt.Println(kids...) // Prints: James Jasmine
fmt.Println(kids)    // Prints: [James Jasmine]

If the reason for the difference in outputs above is not apparent, let me explain. In the first example, we pass a variadic argument, kids..., which passes the kids slice along to the called function, as the variadic argument.

In the second example, we’re passing the slice as a single argument, which in effect gets turned into []any{kids} in the called function.

I’ve made this type of mistake more than once when working with the slog package, which has a number of functions that take a variadic ...any argument. So beware!

Quotes from The Go Programming Language Specification Version of August 2, 2023


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Get daily content like this in your inbox!

Subscribe