查看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:]
我的问题是,上述方法如何达到与"避免数学"方法相同的效果?如果能有一些文档说明这是怎么回事就好了。
This:
picture[i], pixels = pixels[:XSize], pixels[XSize:]
是一个元组赋值。它给picture[i]
赋值,给pixels
赋值。赋值顺序为:pixels[:XSize]
、pixels[XSize:]
。
赋值分两个阶段进行。首先,左边的索引表达式和指针间接(包括选择器中的隐式指针间接)的操作数以及右边的表达式都按照通常的顺序求值。其次,赋值是按照从左到右的顺序进行的。
这里发生的事情是,当循环开始时(i = 0
), picture
的第一个元素(第一行)被赋值为pixels
中的第一个XSize
元素,并且pixels
的切片被重新切片,因此它的第一个元素将是XSize
元素+1。
所以在下一次迭代中,picture[i]
将是picture
中的第二个元素(第二行),同样,pixels
中的第一个XSize
元素将被设置为切片。但是由于在之前的迭代中我们重新切片了pixels
,因此在每次迭代中,它的第一个XSize
元素将是后续的行。
这个元组赋值的例子可以重写为:
for i := range picture {
picture[i]= pixels[:XSize]
pixels = pixels[XSize:]
}
现在更容易看到图片是第一个XSize项像素。
并且像素在每个循环中修改并删除其第一个XSize项。