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

我的问题是上述如何实现与!“避免数学”方法相同的效果?一些关于正在发生的事情的文档会很棒。

4

2 回答 2

5

这:

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

是一个元组赋值。它将一个值分配给 ,并将一个值分配picture[i]pixels。按顺序分配的值是pixels[:XSize]pixels[XSize:]

任务分两个阶段进行。首先,左侧的索引表达式指针间接(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序求值。其次,作业是按从左到右的顺序进行的。

这里发生的情况是,当循环开始 ( i = 0) 时,picture(第一行)的第一个元素被分配一个切片值,该切片值是 中的第一个XSize元素pixels,并且pixels切片被重新切片,因此它的第一个元素将是XSize一个元素 +1。

所以在下一次迭代picture[i]中将是picture(第 2 行)中的第 2 个元素,同样,第一个XSize元素 frompixels将被设置为切片。但是由于在上一次迭代中我们 resliced pixels,在每次迭代中,它的第一个XSize元素将是后续行。

于 2016-10-16T18:27:39.407 回答
2

这个元组赋值示例可以重写为:

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

现在更容易看出图片是第一个XSize像素项。

并且 在每个循环中都会修改该像素并删除其第一个 XSize项。

于 2016-10-16T18:45:44.540 回答