使用go中的范围选择2D切片的2D子切片

时间:2019-02-03 21:33:35

标签: arrays go slice

选择切片的2D子切片时,我得到了令人惊讶的结果。 考虑下面的二维int数组

a := [][]int{
    {0, 1, 2, 3},
    {1, 2, 3, 4},
    {2, 3, 4, 5},
    {3, 4, 5, 6},
}

要使用我要使用的范围来选择左上方的3x3 2D切片

b := a[0:2][0:2]

我希望结果是

[[0 1 2] [1 2 3] [2 3 4]]

但是第二个索引范围似乎没有任何作用,而是返回以下内容:

[[0 1 2 3] [1 2 3 4] [2 3 4 5]]

我想念什么?您能否简单地不选择尺寸> 1的子切片?

1 个答案:

答案 0 :(得分:4)

您无法一步一步完成您想做的事情。切片和数组不是二维的,它们只是组成一个多维对象而构成。参见How is two dimensional array's memory representation

因此,使用切片表达式,您仅获得一个切片,其中将包含“完整”行的子集,其类型将相同:[][]int。如果再次对其进行切片,则只需再次对行的切片进行切片。

还要注意,切片表达式中的较高索引是互斥的,因此a[0:2]仅包含2行,因此您应该使用a[0:3]或简单地使用a[:3]

要获得所需的内容,您必须像这样分别对行进行切片:

b := a[0:3]
for i := range b {
    b[i] = b[i][0:3]
}
fmt.Println(b)

这将输出(在Go Playground上尝试):

[[0 1 2] [1 2 3] [2 3 4]]

或更短:

b := a[:3]
for i, bi := range b {
    b[i] = bi[:3]
}