为什么在 Go 中调用可变参数函数时不能_直接_使用数组?
Why can arrays not be used _directly_ when calling a variadic function in Go?
给定一个 (variadic) 函数
的原因是什么
func varargs(n ...int) {}
可以这样称呼
varargs(1, 2, 3, 4) // Fixed number of arguments
但不是 数组:
a := [4]int{1, 2, 3, 4} // Fixed number of elements
varargs(a...) // Error: cannot use (type [4]int) as type []int in argument
我明白为什么
var s []int = a
不会起作用:它可以防止意外误用,需要手动切片:
s := a[:]
但为什么此限制会扩展到对可变参数函数的调用?
加分题:
相反,为什么调用
func fourargs(w, x, y, z int) {}
与 4 元素数组 类似
fourargs(a...) // Error: not enough arguments in call have ([4]int...)
// want (int, int, int, int)
也被禁止了?
它可以在编译时进行类型检查。
Spec: Passing arguments to ... parameters:
If the final argument is assignable to a slice type []T
, it may be passed unchanged as the value for a ...T
parameter if the argument is followed by ...
. In this case no new slice is created.
因此,当您有一个切片并将其作为可变参数的值传递时,不会创建新切片,它只是被分配。
如果您有一个不同类型的数组,则不能分配给切片类型。所以是不允许的。
您必须先对数组进行切片,无需中间变量即可:
a := [4]int{1, 2, 3, 4}
varargs(a[:]...)
是的,您可以说这种自动切片可以自动/在内部发生。为什么不允许这样做是基于意见的(并且属于 Go 的作者)。基本上,在 Go 中数组是次要的。切片是要走的路。你应该首先有一个切片,你可以通过并且你没有问题。见相关问题: and .
给定一个 (variadic) 函数
的原因是什么func varargs(n ...int) {}
可以这样称呼
varargs(1, 2, 3, 4) // Fixed number of arguments
但不是 数组:
a := [4]int{1, 2, 3, 4} // Fixed number of elements
varargs(a...) // Error: cannot use (type [4]int) as type []int in argument
我明白为什么
var s []int = a
不会起作用:它可以防止意外误用,需要手动切片:
s := a[:]
但为什么此限制会扩展到对可变参数函数的调用?
加分题:
相反,为什么调用
func fourargs(w, x, y, z int) {}
与 4 元素数组 类似
fourargs(a...) // Error: not enough arguments in call have ([4]int...)
// want (int, int, int, int)
也被禁止了?
它可以在编译时进行类型检查。
Spec: Passing arguments to ... parameters:
If the final argument is assignable to a slice type
[]T
, it may be passed unchanged as the value for a...T
parameter if the argument is followed by...
. In this case no new slice is created.
因此,当您有一个切片并将其作为可变参数的值传递时,不会创建新切片,它只是被分配。
如果您有一个不同类型的数组,则不能分配给切片类型。所以是不允许的。
您必须先对数组进行切片,无需中间变量即可:
a := [4]int{1, 2, 3, 4}
varargs(a[:]...)
是的,您可以说这种自动切片可以自动/在内部发生。为什么不允许这样做是基于意见的(并且属于 Go 的作者)。基本上,在 Go 中数组是次要的。切片是要走的路。你应该首先有一个切片,你可以通过并且你没有问题。见相关问题: