这"common idiom"实际上是如何工作的?



查看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项。

相关内容

  • 没有找到相关文章

最新更新