在可变函数中混合 "exploded" 切片和常规参数
mixing "exploded" slices and regular parameters in variadic functions
我想知道为什么不能在 go 中执行以下操作:
func main() {
stuff := []string{"baz", "bla"}
foo("bar", stuff...)
}
func foo(s ...string) {
fmt.Println(s)
}
根据我的理解,slice... "explodes" slice 因此它可以用于多参数函数调用。所以上面的例子实际上应该扩展到foo("bar", "baz", "bla")
。
foo(stuff...)
按预期工作,这并不奇怪,但在上面的示例中,编译器抱怨参数太多。
这是期望的限制吗?我来自 ruby 背景,其中 foo("bar", *stuff)
非常好(而且,至少在我的书中,是同一件事),这就是为什么这让我感到惊讶。
这方面的规范在“Passing arguments to ...
parameters”:
If f
is variadic with a final parameter p
of type ...T
, then within f
the type of p
is equivalent to type []T
.
If f
is invoked with no actual arguments for p
, the value passed to p
is nil
.
Otherwise, the value passed is a new slice of type []T
with a new underlying array whose successive elements are the actual arguments, which all must be assignable to T
.
在你的情况下,东西...在哪里工作:
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.
但是 "bar", stuff...
与上面指定的任何一种情况都不匹配。
T, []T
不匹配 f([]T)
.
可以通过枚举元素或指定可变参数的值,或使用现有切片,由其名称指定其次是 ...
.
您想混合 Go 语言规范 (Passing arguments to ...
parameters) 不允许的 2 种可能方式。
如果使用第一种形式(枚举元素):
The value passed [as the variadic parameter] is a new slice of type []T
with a new underlying array whose successive elements are the actual arguments.
如果使用后者(传递现有切片后跟 ...
)没有创建新切片,您传递的切片将按原样使用。并且传递的切片只能用于指定 one – final – 可变参数的值。尝试同时传递单个元素 和 切片将与函数的签名(在本例中为参数列表)不匹配,您将收到错误消息:
too many arguments in call to foo
Go 中没有实际的 "exploding",这个术语只是用在其他语言中,以帮助形象化传递的数组或切片不会是 元素可变参数的值,但将是可变参数 本身 .
的值
混合 2 需要分配一个新的切片,因为显然不能使用现有的切片。
让它工作的丑陋方法是将它变成一个新的可变参数。
foo(append([]string{"bar"}, stuff...)...)
如果顺序无关紧要:
foo(append(stuff, "bar")...)
我 运行 在准备提供给外部命令的参数时遇到这种情况。如果可能的话,只构建一个单参数切片,然后你不必担心在调用函数时将标量与切片组合起来:
package main
import "os/exec"
func main() {
stuff := []string{"bar"}
stuff = append(stuff, "baz", "bla")
exec.Command("name", stuff...).Run()
}
我想知道为什么不能在 go 中执行以下操作:
func main() {
stuff := []string{"baz", "bla"}
foo("bar", stuff...)
}
func foo(s ...string) {
fmt.Println(s)
}
根据我的理解,slice... "explodes" slice 因此它可以用于多参数函数调用。所以上面的例子实际上应该扩展到foo("bar", "baz", "bla")
。
foo(stuff...)
按预期工作,这并不奇怪,但在上面的示例中,编译器抱怨参数太多。
这是期望的限制吗?我来自 ruby 背景,其中 foo("bar", *stuff)
非常好(而且,至少在我的书中,是同一件事),这就是为什么这让我感到惊讶。
这方面的规范在“Passing arguments to ...
parameters”:
If
f
is variadic with a final parameterp
of type...T
, then withinf
the type ofp
is equivalent to type[]T
.
Iff
is invoked with no actual arguments forp
, the value passed top
isnil
.
Otherwise, the value passed is a new slice of type[]T
with a new underlying array whose successive elements are the actual arguments, which all must be assignable toT
.
在你的情况下,东西...在哪里工作:
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.
但是 "bar", stuff...
与上面指定的任何一种情况都不匹配。
T, []T
不匹配 f([]T)
.
可以通过枚举元素或指定可变参数的值,或使用现有切片,由其名称指定其次是 ...
.
您想混合 Go 语言规范 (Passing arguments to ...
parameters) 不允许的 2 种可能方式。
如果使用第一种形式(枚举元素):
The value passed [as the variadic parameter] is a new slice of type
[]T
with a new underlying array whose successive elements are the actual arguments.
如果使用后者(传递现有切片后跟 ...
)没有创建新切片,您传递的切片将按原样使用。并且传递的切片只能用于指定 one – final – 可变参数的值。尝试同时传递单个元素 和 切片将与函数的签名(在本例中为参数列表)不匹配,您将收到错误消息:
too many arguments in call to foo
Go 中没有实际的 "exploding",这个术语只是用在其他语言中,以帮助形象化传递的数组或切片不会是 元素可变参数的值,但将是可变参数 本身 .
的值混合 2 需要分配一个新的切片,因为显然不能使用现有的切片。
让它工作的丑陋方法是将它变成一个新的可变参数。
foo(append([]string{"bar"}, stuff...)...)
如果顺序无关紧要:
foo(append(stuff, "bar")...)
我 运行 在准备提供给外部命令的参数时遇到这种情况。如果可能的话,只构建一个单参数切片,然后你不必担心在调用函数时将标量与切片组合起来:
package main
import "os/exec"
func main() {
stuff := []string{"bar"}
stuff = append(stuff, "baz", "bla")
exec.Command("name", stuff...).Run()
}