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

我想知道为什么不能在 go 中执行以下操作:


func main() {

    stuff := []string{"baz", "bla"}

    foo("bar", stuff...)

}


func foo(s ...string) {

    fmt.Println(s)

}

在我的理解中,切片...“爆炸”切片,因此它可以用于多参数函数调用。所以上面的例子实际上应该扩展到foo("bar", "baz", "bla").


foo(stuff...) 按预期工作,这里没有意外,但在上面的示例中,编译器抱怨参数太多。


这是一个理想的限制吗?我来自 ruby 背景,其中 afoo("bar", *stuff)非常好(并且,至少在我的书中,是同一件事),这就是为什么这让我感到惊讶。


弑天下
浏览 182回答 3
3回答

慕的地6264312

可变参数的值可以通过枚举元素或使用现有切片指定,由其名称后跟....您想要混合 Go 语言规范(将...参数传递给参数)不允许的 2 种可能方式。如果使用第一种形式(枚举元素):传递的值 [作为可变参数] 是一个新的类型切片,[]T带有一个新的底层数组,其连续元素是实际参数。如果使用后者(传递现有切片,然后是...),则不会创建新切片,则按原样使用您传递的切片。而通过分片只能用于指定的值一个-在最后-可变参数的参数。尝试同时传递单个元素和切片将与函数的签名(在本例中为参数列表)不匹配,并且您将收到错误消息:too many arguments in call to fooGo 中没有实际的“爆炸”,该术语仅在其他语言中使用,以帮助形象化传递的数组或切片将不是可变参数的元素,而是可变参数本身的值。混合 2 需要分配一个新的切片,因为显然不能使用现有的切片。

慕丝7291255

对此的规范在“将...参数传递给参数”:如果f是带有最终参数ptype 的可变参数...T,则在f类型 ofp内等效于 type []T。如果f在没有实际参数的情况下调用p,则传递给的p值为nil。否则,传递的值是一个新的类型切片,[]T带有一个新的底层数组,其连续元素是实际参数,所有参数都必须分配给T。在你的情况下,东西......在哪里工作:如果最后一个参数可分配给切片类型[]T,则...T如果参数后跟.... 在这种情况下,不会创建新切片。但"bar", stuff...不匹配上面指定的任何一种情况。T, []T不匹配f([]T)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go