fmt.Println 中的 Variadic 变量扩展

Variadic Variable Expansion in fmt.Println

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 接受任何值,因为它是一个空接口。

让我感到困惑的是

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

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

我在这里错过了什么?

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

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{} 值,这些值将隐式包装在切片中。

如果您想将 a 的元素传递给需要可变参数 []interface{} 的函数,您必须 "manually" 预先创建该切片,例如:

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

Go Playground 上尝试这些示例。

另见相关问题: