Go随笔之slice

Go 的 slice 底层数据结构是由一个 array 指针指向底层数组,len 表示切片长度,cap 表示切片容量。slice 的主要实现是扩容。对于 append 向 slice 添加元素时,假如 slice 容量够用,则追加新元素进去,slice.len++,返回原来的 slice。当原容量不够,则 slice 先扩容,扩容之后 slice 得到新的 slice,将元素追加进新的 slice,slice.len++,返回新的 slice。

//slice 在函数内没有出现扩容,函数外和函数内 slice 变量指向是同一个数组,
//则函数内复制的 slice 变量值出现更改,函数外这个 slice 变量值也会被修改
func change(bb []int) {
	for k, _ := range bb {
		bb[k] = k + 1
	}
}
//slice 在函数内出现扩容,则函数内变量的值会新生成一个数组
//也就是新的 slice,而函数外的 slice 指向的还是原来的 slice,则函数内的修改不会影响函数外的 slice。
func add(bb []int) {
	bb = append(bb, 1)
}
func main(tt *testing.T) {
	bb := make([]int, 4)
	for i := 0; i < 4; i++ {
		bb[i] = i
	}
	fmt.Println(bb) //[0 1 2 3]
	change(bb)
	fmt.Println(bb) //[1 2 3 4]
	add(bb)
	fmt.Println(bb) //[1 2 3 4]
}

对于切片的扩容规则:当切片比较小时(容量小于 1024),则采用较大的扩容倍速进行扩容(新的扩容会是原来的 2 倍),避免频繁扩容,从而减少内存分配的次数和数据拷贝的代价。当切片较大的时(原来的 slice 的容量大于或者等于 1024),采用较小的扩容倍速(新的扩容将扩大大于或者等于原来 1.25 倍),主要避免空间浪费,网上其实很多总结的是 1.25 倍,那是在不考虑内存对齐的情况下,实际上还要考虑内存对齐,扩容是大于或者等于 1.25 倍。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值