Go:Variadic函数和太多参数?

Med*_*her 10 variadic-functions go

这是我遇到的问题的一个例子:

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...)
}
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我得到了错误too many arguments in call to foo.我想我可以理解为什么会发生这种情况,但我不清楚的是我如何能够绕过它而不必b在开始时使用额外的插槽复制aa(我不想这样做,因为这段代码将经常运行b并且有点长).

所以我的问题是:我只是做错了吗?如果没有,那么做我想做的事情最有效的方法是什么?

(另外,我无法更改签名foo).

def*_*ode 13

在Go运行时一个可变参数函数的实现,如果它已经在最后,而不是可变参数参数的额外片参数.

例如:

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)
Run Code Online (Sandbox Code Playgroud)

从理论上讲,Go可以处理直接指定一些可变参数的情况,其余参数从数组/切片中扩展出来.但是,它效率不高.

//This call
Foo(5, c, b...)

// would be implemented like this.
v := append([]int{c},b...)
FooImpl(5, v)
Run Code Online (Sandbox Code Playgroud)

你可以看到Go会创建一个b反正的副本.Go的精神是尽可能小,但仍然有用.所以像这样的小功能会被丢弃.你或许可以争论这种语法糖,因为它可以比直接的方法更有效地实施append.

请注意,扩展切片...不会创建基础数组的副本以用作参数.该参数只是变量的别名.换句话说,它真的很有效率.


cre*_*ack 8

你可以这样做:

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...)...)
}
Run Code Online (Sandbox Code Playgroud)

在期待时b ...int,您需要传递一个[]int...或者int作为参数.不要不能混用int[]int...