查看golang's 2D slices的文档,无法理解上一个示例中使用的语法:
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:]
我的问题是上面如何实现与“避免数学”方法相同?关于正在发生的事情的一些文档会很棒。
答案 0 :(得分:5)
此:
picture[i], pixels = pixels[:XSize], pixels[XSize:]
是元组assignment。它会为picture[i]
指定一个值,为pixels
指定一个值。按顺序分配的值为pixels[:XSize]
和pixels[XSize:]
。
转让分两个阶段进行。首先,左侧index expressions和pointer indirections的操作数(包括selectors中的隐式指针间接)和右侧的表达式都是evaluated in the usual order。其次,分配按从左到右的顺序进行。
这里发生的是当循环开始时(i = 0
),picture
(第一行)的第一个元素被赋值为一个切片值,即第一个XSize
个元素。 pixels
,pixels
切片已被重置,因此其第一个元素将是XSize
th 元素+1。
因此,在下一次迭代中,picture[i]
将成为picture
(第2行)中的第2个元素,同样,来自XSize
的第一个pixels
元素将是设置为切片。但是因为在上一次迭代中我们重新pixels
,所以在每次迭代中它的第一个XSize
元素将是后续行。
答案 1 :(得分:2)
这个元组赋值示例可以重写为:
for i := range picture {
picture[i]= pixels[:XSize]
pixels = pixels[XSize:]
}
现在更容易看到图片是像素的第一个 XSize 项目。
在每个循环中像素 被修改并删除其第一个 XSize 项目。