如何将切片作为部分函数参数进行解包?

huangapple go评论76阅读模式
英文:

How can I unpack a slice as a partial function argument?

问题

我正在使用exec.Command,它接收一个可变数量的字符串作为其第二个参数。例如:

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

我也可以使用切片并使用...进行解包:

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

但是,将两者混合使用是不起作用的:

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

会出现错误:

./tester.go:12:29: exec.Command调用中的参数太多
        已有 (string, string, []string...)
        期望 (string, ...string)

这让我感到惊讶,因为在Python中类似的操作是可行的。
我尝试寻找这个特定情况的解决方法,但我找到的大多数资源只是关于一般切片的。我已经找到了一个"解决方法"(更像是一个变通方法),即在切片的开头添加"常量"部分,但我想确保我没有漏掉什么:

var args = os.Args
args = append([]string{"script_name.py"}, args...)
out, err := exec.Command("python3", args...).Output()
  1. 我是否漏掉了什么?有没有办法同时传递常量字符串和解包后的数组?
  2. 这里有什么语言限制?为什么要区分string, string, stringstring, string...?我很想更深入地了解这个问题。
英文:

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.

答案1

得分: 3

  1. 不可以。
  2. 约束条件在规范中有详细说明(链接):

> 如果最后一个参数可以赋值给切片类型 []T,并且后面跟着 ...,那么它将作为 ...T 参数的值传递,不会发生变化。

这是唯一一种情况,你可以将切片展开为可变参数,正如你所发现的。

英文:
  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.

huangapple
  • 本文由 发表于 2021年10月27日 21:46:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/69739864.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定