这是我在Golang第一天,当我尝试它的切片操作,如append()
,有一两件事让我很困惑:为什么Golang的切片操作这么复杂
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
a:= s[2:4];
a = append(a, 1000, 1001);
a[1] = 100;
printSlice("a:", a)
printSlice("s:", s)
}
func printSlice(title string, s []int) {
fmt.Printf("%s len=%d cap=%d %v\n", title, len(s), cap(s), s)
}
当我附上只有两个数字到a
,如:
a = append(a, 1000, 1001);
...结果是:
a: len=4 cap=4 [5 100 1000 1001]
s: len=6 cap=6 [2 3 5 100 1000 1001]
我认为,其中的a
显示为参考s
。
但是,当我改变的代码行:
a = append(a, 1000, 1001, 1002);
...结果就变成:
a: len=5 cap=8 [5 100 1000 1001 1002]
s: len=6 cap=6 [2 3 5 7 11 13]
其中,我认为,a
已重新分配的内存另一段,来保存整个事物,并将对s
的引用分开。
这太不一致了,让我感到非常困惑,有时候很容易出现这个错误(例如当你有一个随机数的值附加)。
为什么Golang是这样设计的?如果我只是想要像JavaScript的slice
和push
这样的操作,那怎么能够避免呢?
我认为这个想法是,你只是不'追加到视图共享数据。如果你想采取子碟并追加它,你可以复制一份。 – user2357112
如果您不理解切片背后的简单语义,它只会显得不一致。如果你不确定发生了什么,你可以阅读很多资源:[Go Slices:usage and internals](https://blog.golang.org/go-slices-usage-and-internals),[A游览之旅:切片](https://tour.golang.org/moretypes/7),[切片类型](https://golang.org/ref/spec#Slice_types)和[附加任何复制切片](https://golang.org/ref/spec#Appending_and_copying_slices),[Go By Example:Slices](https://gobyexample.com/slices)和[Slice Tricks](https://github.com/) golang/go/wiki/SliceTricks) – JimB
@ user2357112谢谢,现在我很清楚。 – Kuan