web-dev-qa-db-ja.com

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];
}............

これをコンパイルしようとすると、次のエラーメッセージが表示されます。

配列にバインドされた無効な要素

ここで何が間違っていますか?

48
shutefan

スライスを使用する必要があります。

//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 {
74
Paolo Falabella

私の意見では、これはnewおよびmake関数の使用法に関する混乱から生じています。 golang-nuts でのnew vs makeに関するいくつかの議論から明らかなように、これはGo言語の既知の問題/機能です。

newmakeによって作成された値の型をGoに出力させることで、newmakeの違いがより明確になる場合があります。

_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)の配列要素にアクセスするには、まずポインターを逆参照する必要があります。

newmakeの両方には、最初の引数としてGo型が必要です。ただし、式_[elems]int_はnotGo型です(elemsがGo定数である場合を除き、これはここにケース)。

詳細については、 http://golang.org/doc/go_spec.html#Allocation および http://golang.org/doc/go_spec.html#The_zero_value を参照してください。 。

newの結果が使用可能かどうかをよりよく理解するには、lencapがゼロ(nil)の値で機能するかどうかを調べると便利です。 http://golang.org/doc/go_spec.html#Length_and_capacity

8
user811773

Goプログラミング言語の仕様をご覧ください

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

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

「長さは配列の型の一部です。int型の値で表される負でないconstantに評価される必要があります。」

定数は決して変化しません。

1
Codefor