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

Jon*_*s D 6 arrays go slice

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

a := [][]int{
    {0, 1, 2, 3},
    {1, 2, 3, 4},
    {2, 3, 4, 5},
    {3, 4, 5, 6},
}
Run Code Online (Sandbox Code Playgroud)

要使用范围选择左上角的 3x3 2D 切片,我将使用

b := a[0:2][0:2]
Run Code Online (Sandbox Code Playgroud)

我希望结果是

[[0 1 2] [1 2 3] [2 3 4]]
Run Code Online (Sandbox Code Playgroud)

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

[[0 1 2 3] [1 2 3 4] [2 3 4 5]]
Run Code Online (Sandbox Code Playgroud)

我缺少什么?您是否可以简单地不选择像这样尺寸 > 1 的子切片?

icz*_*cza 7

你不可能一步就能做到你想做的事。切片和数组不是二维的,它们只是组合起来形成一个多维对象。请参阅二维数组的内存表示方式

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

另请注意,切片表达式中的较高索引是排他的,因此a[0:2]只有 2 行,因此您应该使用a[0:3]ora[:3]来代替。

为了得到你想要的,你必须像这样单独对行进行切片:

b := a[0:3]
for i := range b {
    b[i] = b[i][0:3]
}
fmt.Println(b)
Run Code Online (Sandbox Code Playgroud)

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

[[0 1 2] [1 2 3] [2 3 4]]
Run Code Online (Sandbox Code Playgroud)

或者更短:

b := a[:3]
for i, bi := range b {
    b[i] = bi[:3]
}
Run Code Online (Sandbox Code Playgroud)