package main
import "fmt"
func main() {
x1 := [...]int{1, 3, 5} // 数组
s1 := x1[:] // 切片
// s1=[1 3 5],len(s1)=3,cap(s1)=3,0xc0000b6000
fmt.Printf("s1=%v,len(s1)=%v,cap(s1)=%v,%p\n", s1, len(s1), cap(s1), s1)
/*
1 、切片不保存具体的值
2 、切片对应一个底层数组
3 、底层数组都是占用一块连续的内存
*/
s1 = append(s1[:1], s1[2:]...) // 相当于改的是底层数组!!!
// s1=[1 5],len(s1)=2,cap(s1)=3,0xc0000b6000
fmt.Printf("s1=%v,len(s1)=%v,cap(s1)=%v,%p\n", s1, len(s1), cap(s1), s1)
fmt.Println(x1) // [1 5 5]
}
因为 Go 没有删除切片元素的专用方法,那么切片append
的时候,实际是删除了索引为 1 的元素 3,所以切片打印为[1 5]
但是为什么数组最后是[1 5 5]呢?
个人猜测:
因为数组初始化后长度是固定的,不可变更。
所以,切片把数组的索引为 1 的元素 3删除了,进而把元素 5放在了元素 3的索引处,导致数组的值变成了[1 5 5],而数组索引为 2 的元素 5的值及内存地址是没变化的(我比较了 &s1[2] 和 &x1[2] 发现是一样的)。
希望各位 Go 前辈解惑。万分感谢您的回复。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.