go - fmt.Println 中的可变参数扩展

标签 go variadic-functions variadic

package main
import "fmt"
func main(){
        a := []int{1,2,3}
        fmt.Println(a...)
}

运行此命令会出现以下错误

./program.go:5: cannot use a (type []int) as type []interface {} in argument to fmt.Println

来自 godoc fmt Println

func Println(a ...interface{}) (n int, err error)

Println接受任何值,因为它是一个空接口(interface)。

令我困惑的是

fmt.Println(a...)fmt.Println(a[0],a[1],a[2]) 相同

但其中一个有效,但另一个无效。

我在这里缺少什么?

最佳答案

[]int[]interface{} 不同,因此如果您有 []int,则可以' t 将其传递给 fmt.Println() 作为可变参数 slice 的值。您可以按原样传递它,但这将是一个 []interface{} slice ,其中单个值为 []int slice 。

fmt.Println(a...) fmt.Println(a[0],a[1],a[ 2]).

fmt.Println(a[0], a[1], a[2]) 相当于

fmt.Println([]interface{}{a[0], a[1], a[2]}...)

这相当于

fmt.Println([]interface{}{
    interface{}(a[0]),
    interface{}(a[1]),
    interface{}(a[2]),
}...)

因此,当您传递 a[0]a[1]a[2] 时,隐式接口(interface){} 将创建值,这些值将隐式包装在 slice 中。

如果您希望将 a 的元素传递给需要 []interface{} 可变参数的函数,则必须“手动”创建该 slice 事先,例如:

b := make([]interface{}, len(a))
for i, v := range a {
    b[i] = v
}
fmt.Println(b...)

Go Playground 上尝试这些示例.

另请参阅相关问题:Unpacking slice of slices

关于go - fmt.Println 中的可变参数扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55548881/

相关文章:

c++ - 可变参数模板的模板模板参数扩展

c++ - 可变模板类构造函数

node.js - Golang 解密用 Node.js 加密的字符串

go - Golang代理从请求获取RequestURI

http - 从中间件获取 gorilla/mux 路由器当前路由名称

java - 为什么 Java 可变参数不支持集合?

c++ - 与给定类型相似的最广泛可能类型 - C++

c - 编写一个接受可变参数并返回一个值的 C 宏

c++ - 具有变化的返回类型的可变参数模板参数列表

struct - cgo 从 Go : underscore or no underscore? 访问 C 结构字段