Динамически инициализировать размер массива в 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];
}............
При попытке скомпилировать это, я получаю следующее сообщение об ошибке:
недействительный массив, связанный элементами
Что здесь не так?
Ответы
Ответ 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."
Константы отнюдь не меняются.