2016-10-16 1 views
1

この「共通のイディオム」は実際にどのように機能しますか? <a href="https://golang.org/doc/effective_go.html#two_dimensional_slices" rel="nofollow">golang's 2D slices</a>のドキュメントを見て、最後の例で使用される構文を理解することはできません

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

私はこれがドキュメントに追加されたchange requestを発見し、変更の作者は、このコードを理解することは、通常/簡単に持っていた:

罰金:

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

私の質問は、上記の「数学を避ける」方法と同じを達成んどのようにでしょうか?何が起こっているのかについてのいくつかのドキュメントは素晴らしいでしょう。

答えて

5

この:

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

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

割り当ては2つのフェーズで進行します。まず、index expressionspointer indirectionsのオペランド(暗黙的なポインタの間接指定はselectorsにあります)と右側の式はすべてevaluated in the usual orderです。第2に、割り当ては左から右の順序で実行されます。ここで何が起こる

は、ループ開始(i = 0)、picture(最初の行)の最初の要素は、スライス値はpixelsに最初XSize要素であると割り当てられ、場合pixelsスライスがそうreslicedされることです最初の要素はXSizeth要素+1になります。

ので、次の反復picture[i]pictureにおける第2要素(2行目)になり、そして再び、pixelsから最初XSize要素は、スライスとそれに設定されます。しかし、以前の反復ではpixelsを再作成したので、各反復で最初のXSize要素は後続の行になります。

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

それはピクセルのこの最初のXSIZE項目であることを確認するために簡単になりました:

+0

素晴らしい。全く意味をなさない。'(ピクチャ[i]、ピクセル)=(ピクセル[:XSize]、ピクセル[XSize:])'。そのように見ていないだけでした。 – Jonathan

2

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

そして画素ことは、各ループにを改変し、その第一XSIZEアイテムをドロップします。

関連する問題

 関連する問題