7

问:有没有办法在 golang 中定义一个接受任意长度数组作为参数的函数?

例如,

function demoArrayMagic(arr [magic]int){
....
}

我知道在golang中,数组长度是变量类型的一部分,因此以下函数不会接受一个任意数组作为输入

function demoArray(arr [2]int){
....
}

此函数不会arrInput [6]int作为输入进行编译——即,demoArray(arrInput)将无法编译。

此外,接受切片参数的以下函数不接受数组作为参数(不同类型,如预期的那样):

function demoSlice(arr []int){
....
}

即,demoSlice(arrInput)不编译,期望切片而不是数组。

问题是,有没有办法定义一个接受任意长度数组(数组,不是切片)的函数?一种语言强加这种约束看起来很奇怪和限制。

这个问题的意义与动机无关,但就我而言,背后的原因如下。我有一组函数,它们将类型的数据结构作为参数[][]int。我注意到它们的 GOB 序列化比我拥有的其他数据结构慢 10 倍 (MB/s)。我想这可能与切片中的取消引用操作链有关。从切片到数组——即定义类型的对象——[10000][128]int可能会改善情况(我希望如此)。

问候

Ps:我现在提醒一下,Go,“按值”传递/使用事物,使用数组可能是矫枉过正,因为 golang 会复制它们很多次。我想我会继续使用切片,我会尝试稍微了解 GOB 的内部结构。

4

1 回答 1

12

那没有。Go 不支持泛型。

唯一的方法是使用interface{},但这将允许传递任何类型的值,而不仅仅是所需类型的数组。

Go 中的数组是“次要的”。解决方案是根据您的要求使用切片。

这里要注意的一件事是,您可以继续使用数组,并且仅在您要将它们传递给此函数时才对它们进行切片,例如:

func main() {
    a1 := [1]int{1}
    demo(a1[:])

    a2 := [2]int{1, 2}
    demo(a2[:])
}

func demo(s []int) {
    fmt.Println("Passed:", s)
}

上面的输出(在Go Playground上试试):

Passed: [1]
Passed: [1 2]
于 2018-05-16T11:58:18.217 回答