func b() {
x := []int{}
x = append(x, 0)
x = append(x, 1)
x = append(x, 2)
y := append(x, 3)
z := append(x, 6)
fmt.Println(y)
fmt.Println(z)
}
调用函数b 输出结果
[0 1 2 6]
[0 1 2 6]
为什么 y和z输出是一样的?
2、
func b() {
x := []int{}
x = append(x, 0)
x = append(x, 1)
x = append(x, 2)
x = append(x, 3)
y := append(x, 6)
z := append(x, 7)
fmt.Println(y)
fmt.Println(z)
}
x多append一个数,y和z的输出又不一样了, 为什么?
golang版本1.13
有疑问加站长微信联系(非本文作者)

这个属于
入门基础
问题,涉及Slice切片
的底层实现,之前我已经回答过相关的问题,有兴趣看一下类似的问题一、为什么 y 和 z 的结果一样
3个变量都是用同一个底层数组
,且y和z都能访问到第4个元素,而x只能访问到第3个元素二、x多append了一个数,y和z的输出又不一样
len
与cap
一样顺便扔个小博客
Avtion
x := make([]int,0, 3)
这里有个slice扩容的基础知识
规则1: 如果切片的容量
小于1024
个元素,那么扩容的时候slice的cap就直接翻番,乘以2
;一旦元素个数超过1024
个元素,cap扩容就要减缓,变成了四分之一,乘以0.25
,即每次增加原来容量的四分之一。规则2: 如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。
上面的例子验证了规则1
1楼的例子验证了规则2
相信这些应该能够解开你的疑惑
其实
如果切片的容量小于1024个元素,那么扩容的时候slice的cap就直接翻番,乘以2;一旦元素个数超过1024个元素,cap扩容就要减缓,变成了四分之一,乘以0.25,即每次增加原来容量的四分之一
这个说法并不准确,具体扩容的大小还得看容器元素是否能内存对齐
,例如是和int类型的切片连续追加3次容量是4有出入的
感谢大佬详细的回复,学习了 @avtion