1. ホーム
  2. go

[解決済み] Goで2Dスライスを作成する簡潔な方法は何ですか?

2022-04-26 13:23:44

質問

を見ながら、囲碁を勉強しています。 囲碁のツアー . その中で、2Dのスライスを作成する課題がありました。 dy の行と dx を含むカラム uint8 . 私が現在行っている、うまくいく方法は、次のとおりです。

a:= make([][]uint8, dy)       // initialize a slice of dy slices
for i:=0;i<dy;i++ {
    a[i] = make([]uint8, dx)  // initialize a slice of dx unit8 in each of dy slices
}

スライスを初期化するために、それぞれのスライスを反復するのは冗長すぎると思います。また、スライスの次元数が多くなると、コードが扱いにくくなります。Goで2D(またはn次元)スライスを初期化する簡潔な方法はないでしょうか?

どのように解決するのですか?

スライスは常に1次元ですが、より高い次元のオブジェクトを構築するために合成することができるからです。詳しくはこの質問をご覧ください。 Go: 2次元配列のメモリ表現はどうなっているのですか? .

その上で簡略化できることのひとつは for range という構文があります。

a := make([][]uint8, dy)
for i := range a {
    a[i] = make([]uint8, dx)
}

また、スライスの初期化で 複合リテラル の場合、例えば "free" ではこのようになります。

a := [][]uint8{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]

しかし、これにはいくつかのコツがあります。つまり、すべての値を列挙する必要はなく、その中の ゼロ値 スライスの要素タイプの これについての詳細は golangの配列初期化におけるキー項目 .

例えば、最初の10個の要素が0であるスライスが必要な場合、次のようになります。 12 というように作成することができます。

b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]

また、もしあなたが 配列 の代わりに スライス であれば、非常に簡単に作成することができます。

c := [5][5]uint8{}
fmt.Println(c)

出力は

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

配列の場合、配列は記述子ではなく値なので、配列の外側を繰り返し処理したり、配列の内側を初期化したりする必要はありません。ブログ記事参照 配列、スライス(と文字列)。append'の仕組み をご覧ください。

の例を試してみてください。 囲碁プレイグラウンド .