2016-10-01 25 views
15

私は学習していますA Tour of Goを経由して行く。そこにある演習の1つでは、dy行とdx列の2Dスライスを作成してuint8を含むように求めています。私はそれを初期化するために、各スライスを反復することはあまりにも冗長であることを考えるGoで2Dスライスを作成する簡潔な方法は何ですか?

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次元)スライスを初期化する簡潔な方法はありますか?

答えて

25

を、あなたがやったことは「正しい」方法です。スライスは常に1次元であるが、より高次元のオブジェクトを構成するように構成されている可能性があるからである。詳細については、この質問を参照してください:Go: How is two dimensional array's memory representation。例えば、

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

はまた、あなたがcomposite literalとあなたのスライスを初期化した場合、あなたは「無料」のためにこれを取得することに注意してください:あなたはそれを簡素化することができ

ことの一つは、for range構文を使用することです

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

はい、すべての要素を列挙しなければならないようですが、これには限界があります。いくつかのトリックがあります。つまり、すべての値を列挙する必要はなく、スライスの要素タイプのzero valuesでないものだけです。詳細については、Keyed items in golang array initializationを参照してください。例えば

あなたが最初の10個の要素はゼロであり、その後、12を次のスライスをしたい場合、それは次のように作成することができます。

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

はまた、あなたの代わりにarraysを使用したい場合に注意slicesの、それは非常に簡単に作成することができます。

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]] 

配列の場合、配列は記述子ではなく値であるため、配列の場合、「外側」配列を反復処理して「内側」配列を初期化する必要はありません。詳細はブログ投稿Arrays, slices (and strings): The mechanics of 'append'を参照してください。

Go Playgroundの例をお試しください。私は2次元配列の行を交換するために、この機能を書いた

0

あなたは、コードのこの部分参照することができます - より簡潔な方法はありません

package main 

import "fmt" 

func main() { 
    var row, col int 
    fmt.Print("enter rows cols: ") 
    fmt.Scan(&row, &col) 

    // allocate composed 2d array 
    a := make([][]int, row) 
    for i := range a { 
     a[i] = make([]int, col) 
    } 

    // array elements initialized to 0 
    fmt.Println("a[0][0] =", a[0][0]) 

    // assign 
    a[row-1][col-1] = 7 

    // retrieve 
    fmt.Printf("a[%d][%d] = %d\n", row-1, col-1, a[row-1][col-1]) 

    // remove only reference 
    a = nil 
    // memory allocated earlier with make can now be garbage collected. 
} 

Reference

+3

は 'range'のほかに、私はOPが尋ねたものの違いや、あなたのコード例を参照してくださいに失敗します。 – eduncan911

-1

func lchange(l1 int, l2 int, a [][]float64) { 
    b := make([]float64, 1) 
    b = a[l1][:] 
    a[l1] = a[l2] 
    a[l2] = b 
} 
+0

これは質問には関係ありません。 – hazrmard

関連する問題