一尘不染

在可变函数中混合“爆炸”的切片和常规参数

go

我想知道为什么无法进行以下操作:

func main() {
    stuff := []string{"baz", "bla"}
    foo("bar", stuff...)
}

func foo(s ...string) {
    fmt.Println(s)
}

以我的理解,slice …“爆炸”切​​片,因此可以将其用于多参数函数调用。因此,上述示例实际上应扩展为foo("bar", "baz", "bla")

foo(stuff...) 可以正常工作,在这里并不奇怪,但是在上面的示例中,编译器抱怨参数过多。

这是理想的限制吗?我来自一个foo("bar", *stuff)很好的红宝石背景(至少在我的书中也是一样),这就是为什么这让我感到惊讶。


阅读 232

收藏
2020-07-02

共1个答案

一尘不染

可变参数的值 可以 通过枚举元素来指定, 也可以 使用现有切片(由其名称后跟来指定)来指定...

您想混合Go语言规范不允许的2种可能方式(...参数传递给parameter)。

如果使用第一种形式(枚举元素):

传递的值(作为可变参数)是具有新的[]T基础数组的类型的新切片,其后续元素是实际参数。

如果使用后者(传递现有切片,然后传递...),则 不会创建新的切片 ,则传递的 切片将照 原样使用。而通过分片只能用于指定的值
一个 -在 最后 -可变参数的参数。尝试同时传递单个元素 切片将不匹配函数的签名(在这种情况下为参数列表),并且会出现错误:

too many arguments in call to foo

Go中没有实际的“爆炸”,该术语仅在其他语言中用于帮助可视化传递的数组或切片将不是可变参数的 元素 ,而是可变参数 本身 的值。

混合使用2将需要分配新的片,因为显然无法使用现有的片。

2020-07-02