扩容后容量变化
向切片新增一个元素时,若该切片容量已满,会首先根据切片容量进行判断,小于1024字节扩容为原有容量的2倍,大于1024字节扩容为原有容量的1.25倍
扩容前容量小于1024
func main(){
array := [4]int{10, 20, 30, 40}
oldSlice := array[:]
fmt.Printf("len = %d, cap = %d\n", len(oldSlice), cap(oldSlice))
newSlice := append(oldSlice, 50)
fmt.Printf("len = %d, cap = %d\n", len(newSlice), cap(newSlice))
}
运行结果
len = 4, cap = 4
len = 5, cap = 8
扩容前容量大于等于1024
func main(){
var array [1024]int
for i := 0; i < 1024; i++ {
array[i] = i
}
newTestSlice := array[:]
fmt.Printf("len = %d, cap = %d\n", &newTestSlice, len(newTestSlice), cap(newTestSlice))
newTestSlice = append(newTestSlice, 1025)
fmt.Printf("len = %d, cap = %d\n", &newTestSlice, len(newTestSlice), cap(newTestSlice))
}
运行结果
len = 1024, cap = 1024
len = 1025, cap = 1280
扩容后数组指向
若原切片还有容量可以扩容,执行append操作是对原有切片进行,所以这种情况下,扩容以后的数组还是指向原来的数组,扩容后的数组中某一个值的修改会影响原切片与原数组
func main(){
array := [4]int{10, 20, 30, 40}
oldSlice := array[0:2]
newSlice := append(oldSlice, 50)
fmt.Printf("Before slice = %v,len = %d, cap = %d\n", oldSlice, len(oldSlice), cap(oldSlice))
fmt.Printf("Before newSlice = %v, len = %d, cap = %d\n", newSlice, len(newSlice), cap(newSlice))
newSlice[1] += 10
fmt.Printf("After slice = %v, len = %d, cap = %d\n", oldSlice, len(oldSlice), cap(oldSlice))
fmt.Printf("After newSlice = %v, len = %d, cap = %d\n", newSlice, len(newSlice), cap(newSlice))
fmt.Printf("After array = %v\n", array)
}
运行结果
Before slice = [10 20],len = 2, cap = 4
Before newSlice = [10 20 50], len = 3, cap = 4
After slice = [10 30], len = 2, cap = 4
After newSlice = [10 30 50], len = 3, cap = 4
After array = [10 30 50 40]
向原有切片新增一个元素生成新切片时,若原切片已满,Go 默认会先开一片内存区域,把原来的值拷贝过来,然后再执行 append() 操作,这种情况不影响原数组
func main(){
array := [4]int{10, 20, 30, 40}
oldSlice := array[:]
newSlice := append(oldSlice, 50)
fmt.Printf("Before slice = %v,len = %d, cap = %d\n", oldSlice, len(oldSlice), cap(oldSlice))
fmt.Printf("Before newSlice = %v, len = %d, cap = %d\n", newSlice, len(newSlice), cap(newSlice))
newSlice[1] += 10
fmt.Printf("After slice = %v, len = %d, cap = %d\n", oldSlice, len(oldSlice), cap(oldSlice))
fmt.Printf("After newSlice = %v, len = %d, cap = %d\n", newSlice, len(newSlice), cap(newSlice))
fmt.Printf("After array = %v\n", array)
}
运行结果
Before slice = [10 20 30 40],len = 4, cap = 4
Before newSlice = [10 20 30 40 50], len = 5, cap = 8
After slice = [10 20 30 40], len = 4, cap = 4
After newSlice = [10 30 30 40 50], len = 5, cap = 8
After array = [10 20 30 40]