【Go语言学习】切片Slice的扩容机制

扩容后容量变化

向切片新增一个元素时,若该切片容量已满,会首先根据切片容量进行判断,小于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]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值