Variadic arguments

176 views
Skip to first unread message

Matthew Zimmerman

unread,
Aug 29, 2014, 12:54:15 PM8/29/14
to golang-nuts
I thought this would compile:

func main() {
arglist := []string{"three", "four"}
_ = exec.Command("one", "two", arglist...)
}

Given that exec.Command takes a variadic (...string) as it's last
argument, I thought I could pass in a combination of implicit strings
and a compiler expanded slice.

Why can't I? The spec does imply that an expanded slice can only be
used one-for-one with a variadic argument.
https://golang.org/ref/spec#Passing_arguments_to_..._parameters

http://play.golang.org/p/MjlzcNl4Ry

Thanks,
Matt

Caleb Spare

unread,
Aug 29, 2014, 1:17:11 PM8/29/14
to Matthew Zimmerman, golang-nuts
https://golang.org/doc/faq#convert_slice_of_interface
https://code.google.com/p/go-wiki/wiki/InterfaceSlice
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Matthew Zimmerman

unread,
Aug 29, 2014, 2:32:13 PM8/29/14
to Caleb Spare, golang-nuts
I don't think those references are actually applicable to my question.
I'm not trying to convert to/from interface{} or []interface{} but use
the ... "operator" (what is its name?) to convert from []string to
...string.

The compiler does that nicely for you for []string{"a","b"}... to
...string, it just doesn't automagically convert
"a","b","c",[]string{"d","e"}... to ...string -- makes sense to me why
it doesn't when I explain it this way.

Caleb Spare

unread,
Aug 29, 2014, 2:40:35 PM8/29/14
to Matthew Zimmerman, golang-nuts
Ah sorry, I didn't read your question closely enough and
pattern-matched it to a very common slice question :)

I think the relevant bit of the spec is

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

Essentially, if you use f(x, y, z...) it's a very small amount of
sugar for passing a slice as the last argument of the function:
calling f(T1, ...T2) as f(x, y...) is the same if it were f(T1, []T2)
and you called it as f(x, y). So if you call it as f(x, y, z...)
you're passing in more arguments than the function takes, even if y
has type T2.

On Fri, Aug 29, 2014 at 11:31 AM, Matthew Zimmerman

Rob Pike

unread,
Aug 29, 2014, 2:41:05 PM8/29/14
to Matthew Zimmerman, Caleb Spare, golang-nuts
It would require another allocation to put "two" and arglist into a
single slice. If you really want it, you can write the allocation
yourself.

-rob

Matt Harden

unread,
Aug 29, 2014, 2:43:50 PM8/29/14
to Matthew Zimmerman, Caleb Spare, golang-nuts
There's actually no conversion; there is no type called ...string. The ellipsis (...) just indicates a variadic function. In Go, a variadic function receives a slice as its last parameter. The compiler automatically converts the last arguments in a call to the function into a slice. It also supplies another function call syntax with the ellipsis to directly pass the final argument as a slice. But as you noticed, it does not automatically tack additional arguments on to the slice.
Reply all
Reply to author
Forward
0 new messages