GolangSlice扩容细节

/*
   切片没有自己的任何数据,它只是底层数组的一个表示。对切片所做的任何修改都将反映在底层数组中。
*/
a := [5]int{1, 2, 3, 4, 5}
b := a[:3]
c := make([]int, 2, 5) //make一般是2个参数,第三个参数为预留参数,定义slice的cap大小
for i := 0; i < len(b); i++ {
   b[i]++
}
fmt.Println(a) //此处,a的部分元素的值发生了改变
fmt.Println(reflect.TypeOf(b))
fmt.Println(c)
c[0] = 1
//c = append([]int{2}, []int{2, 3}...)
c = c[:cap(c)] //需要重新分配切片才能试用cap-len的预留空间
fmt.Println(c, len(c), cap(c))

s := []int{1, 2, 3}
v := s
fmt.Println("a", s[2:])
//s[1] = 3
s = append(s[:1], s[2], s[2], s[2]) //s[:1] = 数组s中的元素1,append s[2:]时,其容量是够的,会在s[0]后面接一个元素s[2],导致底层数组[1,2,3]变成[1,3,3]
fmt.Println("s的容量为", cap(s))
s = s[:cap(s)]
s[5] = 1
fmt.Println(s)
fmt.Println("v=", v) //此时v仍指向旧数组[1,2,3]
fmt.Println("s=", s) //由于原切片s[:1]执行append,容量不足以装下3个数,会重新分配新的底层数组
d := make([]int, 4, 4)
d[0] = 1
d[1] = 2
fmt.Println(cap(d))
d = append(d[:2], []int{22, 34, 66}...)
fmt.Println(d, len(d), cap(d))

m := make([]int, 2, 4)
m = append(m, 1)
m = append(m, 2) //执行到这一步之后,slice的容量满了,下一步继续append会使底层丢弃原有的数组,重建一个数组,此时cap = 2 * max(len(m),len(params)) = 8
fmt.Println(cap(m))
m = append(m, 3)
fmt.Println("m=", m, len(m), cap(m))

aa := []byte{1, 3, 4}
aa = append(aa, 1)
fmt.Println("aa的容量为", cap(aa)) //byte扩容后的cap是 3 * 2 -> 8 没有6字节一说,所以向上取最小为8字节
cc := []int32{1, 23}
cc = append(cc, 2, 5, 6)
fmt.Println("cap of cc is ", cap(cc))

var aaa byte = 1
var bbb int32 = 1
fmt.Println(unsafe.Sizeof(aaa))
fmt.Println(unsafe.Sizeof(bbb))

golang内部对于内置类型, 有着特定的扩容方式,而对于自定义类型的切片的容量计算就是直接 cap = oldcap + append()函数中追加的容量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值