代码:
func main() {
a := []int{1, 2}
printSlice("a", a)
b := a[0:1]
printSlice("b origin", b)
b = append(b, 9)
printSlice("b after append b without growing capacity", b)
printSlice("a after append b without growing capacity", a)
b = append(b, 5, 7, 8)
printSlice("a after append b with grown capacity", a)
printSlice("b after append b with grown capacity", b)
b[0] = 1000
printSlice("b", b)
printSlice("a", a)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
输出:
a len=2 cap=2 [1 2]
b origin len=1 cap=2 [1]
b after append b without growing capacity len=2 cap=2 [1 9]
a after append b without growing capacity len=2 cap=2 [1 9]
a after append b with grown capacity len=2 cap=2 [1 9]
b after append b with grown capacity len=5 cap=6 [1 9 5 7 8]
b len=5 cap=6 [1000 9 5 7 8]
a len=2 cap=2 [1 9]
有趣的事情出现在最后两个打印行。我已经知道切片只是底层数组的一个窗口。当在其容量内重新切片时,那么两个切片共享相同的底层数组,但是当我将其重新切片以扩大其容量时,这两个切片具有不同的底层数组。但是,为什么golang设计者选择不更改原始切片的底层数组为新切片的底层数组,使得两个切片仍然具有相同的底层数组呢?在当前状态下,当我更改新重新切片的某些元素的值时,我必须检查是否更改了底层数组,以决定此操作是否会对由它支持的其他切片产生副作用(请参见输出的最后两行)。我认为这很尴尬。