Home > Mobile >  How can I unpack a slice as a partial function argument?
How can I unpack a slice as a partial function argument?

Time:10-28

I'm using exec.Command that receives a variable number of strings for its second parameter. For example:

out, err = exec.Command("python3", "script_name.py", "argument", "--flag", "--another")

I can also use a slice and unpack it using ...:

var args = []string{"script_name.py", "argument", "--flag", "--another"}
out, err = exec.Command("python3", args...)

BUT mixing the two does not work:

var args = []string{"argument", "--flag", "--another"}
out, err = exec.Command("python3", "script_name.py", args...)

fails with:

./tester.go:12:29: too many arguments in call to exec.Command
        have (string, string, []string...)
        want (string, ...string)

This is surprising to me since something similar would work in python. I've tried looking for this specific case but most of the resources I found are just about slicing in general. I've "solved" it (more like a workaround) by prepending the "constant" part to the start of the slice, but wanted to make sure I'm not missing anything:

var args = os.Args
args = append([]string{"script_name.py"}, args...)
out, err := exec.Command("python3", args...).Output()
  1. Am I missing anything? Is there a way to pass both the constant string and the unpacked array?
  2. What are the language constraints here? Why is it distinguishing between string, string, string and string, string...? I'd love to understand this more deeply.

CodePudding user response:

  1. No.

  2. The constraints are detailed in the spec:

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.

That is the only case in which you can explode a slice into a variadic parameter, as you have found.

  •  Tags:  
  • go
  • Related