Функция, которая принимает массив произвольного размера в качестве аргумента (возможно ли это в Golang?)

Q: Есть ли способ, в 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 раз медленнее (МБ / с), чем у других структур данных, которые у меня есть. Я полагаю, что это может быть связано с цепочкой операций разыменования в срезах. Переход от слайсов к массиву - т.е. определение объектов типа [10000][128]int- могу улучшить ситуацию (надеюсь).

С уважением

Ps: я напоминаю теперь, что Go, передает / использует вещи "по значению", использование массивов может быть излишним, потому что Голанг будет копировать их много раз. Я думаю, что я останусь с кусочками, и я попытаюсь немного понять внутренности GOB.

1 ответ

Решение

Нет. 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]
Другие вопросы по тегам