引用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]
使用一片切片
切片(切片标头)类似于指针:它们是类似结构的小型数据结构,其中包含指向切片第一个元素的指针,指向底层数组中的某个位置。详情见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