go array和slice的区别

88 篇文章 0 订阅

相同点

属于集合类的类型,值都可以用来存储某一种类型的值(或者说元素)

区别(最大的不同)

数组的长度固定,数组是值类型(值类型有基本数据类型,结构体类型)slice的值长度可变,属于引用类型(引用类型:字典类型,通道类型,函数类型)切片是引用传递,所以它们不需要使用额外的内存并且比使用数组更有效率。

如果传递的是引用类型,那么就是“传引用”,如果传递的是值类型,那么就是“传值”(会把以前的数据复制一遍)

数组长度在声明的时候就必须给定,并且之后不会再改变。

slice类型的字面量中只有元素类型,没有长度。切片长度可以自动随着元素数量的增长而增长,但不会随着元素数量的减少而减少。

数组的容量=长度,不可改变。

slice组成

一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。通过len和cap函数分别返回slice的长度和容量。

一旦一个slice无法容纳更多的元素,go会扩容,但不会改变原来的切片,而是会生成一个容量更大的slice,然后把原有的元素和新元素一起copy到新的slice中。一般情况下,可简单认为新slice的容量是旧slice容量的2倍。

但是当原slice的长度>= 1024,go会以原容量的1.25倍作为新容量的基准,新容量基准会不断与1.25相乘,直到结果不小于原长度与要追加的元素数量之和。最终,新容量要比新长度要大 一些。

如果一次追加的元素过多,以至于使新长度比原容量的2倍还要大,那么新容量就会以新长度为基准。

 

一个slice的底层数组永远不会倍替换,虽然在扩容的时候,go一定会生成新的底层数组,但同时也生成了新的 slice。只是把新slice作为了新底层数组的窗口,而没有对原slice及其底层数组做任何改动。

在无需扩容的时候,append函数返回的是指向原底层数组的新slice。而在需要扩容的时候,append函数返回的是指向新底层数组的新的slice

slice扩容策略

https://blog.csdn.net/m0_37579159/article/details/79344056 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值