[英]Go: Variadic function and too many arguments?
Here's an example of the problem I'm having: 这是我遇到的问题的一个例子:
package main
import "fmt"
func foo(a int, b ...int) {
fmt.Println(a,b)
}
func main() {
a := 0
aa := 1
b := []int{2,3,4}
foo(a, aa, b...)
}
When I run this I get the error too many arguments in call to foo
. 当我运行这个时,我
too many arguments in call to foo
得到的错误too many arguments in call to foo
。 I guess I could understand why this is happening, but what's not clear to me is how I can get around it without having to make a copy of b
with an extra slot at the beginning for aa
(which I'd rather not do, as this code would be running quite often and with b
being somewhat long). 我想我能理解为什么会发生这种情况,但我不清楚的是我怎么能绕过它而不必在开头为
aa
制作一个带有额外插槽的b
副本(我宁愿不这样做,因为这段代码会经常运行,并且b
有点长)。
So my question is: Am I just doing this wrong? 所以我的问题是:我只是做错了吗? And if not, what would be the most efficient way to do what I'm trying to do?
如果没有,那么做我想做的事情最有效的方法是什么?
(Also, I can't change the signature of foo
). (另外,我无法改变
foo
的签名)。
In the Go runtime a variadic function is implemented as if it had an extra slice parameter at the end instead of a variadic parameter. 在Go运行时一个可变参数函数的实现 ,如果它已经在最后,而不是可变参数参数的额外片参数。
For example: 例如:
func Foo( a int, b ...int )
func FooImpl( a int, b []int )
c := 10
d := 20
//This call
Foo(5, c, d)
// is implemented like this
b := []int{c, d}
FooImpl(5, b)
In theory Go could handle the case where some of a variadic arguments are specified directly and the rest are expanded out of an array/slice. 从理论上讲,Go可以处理直接指定一些可变参数的情况,其余参数从数组/切片中扩展出来。 But, it would not be efficient.
但是,它效率不高。
//This call
Foo(5, c, b...)
// would be implemented like this.
v := append([]int{c},b...)
FooImpl(5, v)
You can see that Go would be creating a copy of b
anyways. 你可以看到Go无论如何都会创建一个
b
的副本。 The ethos of Go is to be as small as possible and yet still useful . Go的精神是尽可能小,但仍然有用 。 So small features like this get dropped.
所以像这样的小功能会被丢弃。 You may be able to argue for this syntactic sugar, as it can be implemented slightly more efficiently than straight forward approach of
append
. 你或许可以争论这种语法糖,因为它可以比直接的
append
方法更有效地实施。
Note that expanding a slice with ...
does not create a copy of the underlying array for use as the parameter. 请注意, 使用
...
扩展切片不会创建基础数组的副本以用作参数。 The parameter just aliases the variable. 该参数只是变量的别名。 In other words it's really efficient.
换句话说,它真的很有效率。
You can do something like this: 你可以这样做:
package main
import "fmt"
func foo(a int, b ...int) {
fmt.Println(a,b)
}
func main() {
a := 0
aa := 1
b := []int{2,3,4}
foo(a, append([]int{aa}, b...)...)
}
When expecting b ...int
, you need to pass a []int...
or int
's as parameters. 当期望
b ...int
,你需要传递一个[]int...
或int
作为参数。 Don't can't mix int
and []int...
不要混用
int
和[]int...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.