1

golang の 2D スライスのドキュメントを見て、最後の例で使用されている構文を理解できません。

func main() {
    XSize := 5
    YSize := 5

    // Allocate the top-level slice, the same as before.
    picture := make([][]uint8, YSize) // One row per unit of y.

    // Allocate one large slice to hold all the pixels.
    pixels := make([]uint8, XSize*YSize) // Has type []uint8 even though picture is [][]uint8.

    // Loop over the rows, slicing each row from the front of the remaining pixe ls slice.
    for i := range picture {
        picture[i], pixels = pixels[:XSize], pixels[XSize:]
    }
}

これがドキュメントに追加され、変更の作成者がこの通常の/理解しやすいコードを持っている変更リクエストを見つけました:

// Loop over the rows, slicing each row.
for i := range picture {
     picture[i] = pixels[i*XSize:(i+1)*XSize]

ただし、次のコメントがあります。

大丈夫。別の一般的なイディオムは、数学を避けることです:

picture[i], pixels = pixels[:XSize], pixels[XSize:]

私の質問は、上記が !"avoid the math" メソッドと同じことをどのように達成するのかということです。何が起こっているかについてのいくつかのドキュメントは素晴らしいでしょう。

4

2 に答える 2

5

これ:

picture[i], pixels = pixels[:XSize], pixels[XSize:]

タプル代入です。に値を割り当て、 に値を割り当てpicture[i]ますpixels。順番に割り当てられる値はpixels[:XSize]、 とpixels[XSize:]です。

割り当ては 2 つのフェーズで進行します。最初に、左側のインデックス式ポインター間接参照 (セレクターの暗黙的なポインター間接参照を含む) のオペランドと右側の式がすべて通常の順序で評価されます。次に、割り当ては左から右の順序で実行されます。

ここで何が起こるかというと、ループが始まると ( i = 0)、 (最初の行) の最初の要素に の最初の要素でpictureあるスライス値が割り当てられ、最初の要素が番目の要素 +1になるようにスライスが再スライスされます。XSizepixelspixelsXSize

したがって、次の反復picture[i]ではpicture(2 行目) の 2 番目の要素になり、再び最初のXSize要素pixelsがスライスとして設定されます。しかし、前の繰り返しで を再スライスしたpixelsため、各繰り返しで最初のXSize要素が後続の行になります。

于 2016-10-16T18:27:39.407 に答える
2

このタプル割り当ての例は、次のように書き直すことができます。

for i := range picture {
    picture[i]= pixels[:XSize]
    pixels = pixels[XSize:]
}

画像がこの最初のXSizeのpixelアイテムであることが簡単にわかります。

そして、その ピクセル は各ループで変更され、最初のXSizeアイテムが削除されます。

于 2016-10-16T18:45:44.540 に答える