如何创建非连续数组索引切片

问题描述 投票:3回答:1

我试图更好地了解切片。

例如,在Fortran中,如果我有一个二维数组,则可以使用matrix(:, (/2, 5, 9/))创建切片。该切片仅包含第2、5和9行。我正在尝试寻找一种在Go中创建类似切片的方法。

我知道我可以像这样使用append:

var slice [][N]
slice = append(arr[1],arr[4],arr[8])

并且切片具有正确的值,但是append复制值,所以如果我更新数组,则切片不会更新。

Go中是否有正确的方法?

arrays go slice
1个回答
2
投票

Spec: Slice types:引用

切片是基础数组的连续段的描述符,并提供对该数组中元素编号序列的访问。

切片始终表示基础数组的连续段,不能在开始索引和结束索引之间跳过元素。

使用切片指针

您可以使用指针来模仿行为,但随后它们将成为具有各自优点和缺点的指针。例如:

const N = 3

s := make([][N]int, 10)
s[2] = [3]int{20, 21, 22}
s[5] = [3]int{50, 51, 52}
s[9] = [3]int{90, 91, 92}

s2 := []*[N]int{&s[2], &s[5], &s[9]}
for _, p := range s2 {
    fmt.Print(*p, " ")
}

s[2][0] = 66
fmt.Println()
for _, p := range s2 {
    fmt.Print(*p, " ")
}

[从s2的元素创建并填充s后,我们修改s的元素,然后再次打印s2,然后看到更改后的更新值。输出(在Go Playground上尝试):

[20 21 22] [50 51 52] [90 91 92] 
[66 21 22] [50 51 52] [90 91 92]

使用一片切片

Slice(切片标头)类似于指针:它们是类似结构的小型数据结构,其中包含指向切片的第一个元素的pointer,指向基础数组中的某个位置。有关详细信息,请参见Are golang slices passed by value?why slice values can sometimes go stale but never map values?

因此,如果您使用切片的切片而不是数组的切片,它将在没有指针的情况下工作(切片值已包含指针)。

请参见此示例:

s := make([][]int, 10)
s[2] = []int{20, 21, 22}
s[5] = []int{50, 51, 52}
s[9] = []int{90, 91, 92}

s2 := [][]int{s[2], s[5], s[9]}
fmt.Println(s2)

s[2][0] = 66
fmt.Println(s2)

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

[[20 21 22] [50 51 52] [90 91 92]]
[[66 21 22] [50 51 52] [90 91 92]]

请参阅相关问题:How is two dimensional array's memory representation

© www.soinside.com 2019 - 2024. All rights reserved.