Подтвердить что ты не робот

Динамически инициализировать размер массива в go

Я пытаюсь написать небольшое приложение в go, которое принимает "x" число целых чисел из стандартного ввода, вычисляет среднее значение и возвращает его. До сих пор я получил:

func main() {
var elems, mean int
sum := 0

fmt.Print("Number of elements? ")

fmt.Scan(&elems)

var array = new([elems]int)

for i := 0; i < elems; i++ {
    fmt.Printf("%d . Number? ", i+1)
    fmt.Scan(&array[i])
    sum += array[i];
}............

При попытке скомпилировать это, я получаю следующее сообщение об ошибке:

недействительный массив, связанный элементами

Что здесь не так?

4b9b3361

Ответ 1

Вы должны использовать слайс вместо массива:

//var array = new([elems]int) - no, arrays are not dynamic
var slice = make([]int,elems) // or slice := make([]int, elems)

См. "Использование разделов и внутренних частей".

Также вы можете рассмотреть возможность использования диапазона для вашего цикла:

// for i := 0; i < elems; i++ { - correct but less idiomatic
for i, v := range slice {

Ответ 2

По-моему, это связано с путаницей использования функций new и make. Это известная проблема/функция на языке Go, о чем свидетельствуют несколько дискуссий о new vs make в golang-nuts.

Разница между new и make может стать яснее, если вы отпустите "Отпечатать" тип значения, созданного с помощью new и make:

package main

import "fmt"

func main() {
    fmt.Printf("%T  %v\n", new([10]int), new([10]int))
    fmt.Printf("%T  %v\n", make([]int, 10), make([]int, 10))
}

Выход:

*[10]int  &[0 0 0 0 0 0 0 0 0 0]
[]int  [0 0 0 0 0 0 0 0 0 0]

Как видно из типа, для доступа к элементу массива new([10]int) нам сначала нужно разыменовать указатель.

Оба new и make требуют типа Go в качестве первого аргумента. Однако выражение [elems]int не является типом Go (если elems не является константой Go, что здесь не так).

Подробнее см. http://golang.org/doc/go_spec.html#Allocation и http://golang.org/doc/go_spec.html#The_zero_value.

Чтобы лучше понять, можно ли использовать результат new, может быть полезно найти, работают ли len и cap с нулевыми значениями: http://golang.org/doc/go_spec.html#Length_and_capacity

Ответ 3

См. Спецификацию языка программирования Go

http://golang.org/ref/spec#Array_types

http://golang.org/ref/spec#Constants

В нем говорится: "Длина является частью типа массива, она должна оценивать неотрицательную константу, представляемую значением типа int."

Константы отнюдь не меняются.