Go切片扩容机制

首先,我们创建一个数组

image-20220120221720455

然后我们又声明了一个s1变量,把数组s分片,此时s1是一个切片,切片有三个域,其中一个存的就是数组指针,它就指向了这个数组1号下标,然后长度为2,容量为5。

image-20220120221854638

然后我们再声明一个s2变量,也是把数组s分片,此时就是如下图所示。

image-20220120222103988

如果此时我们修改s的值,如果在s1和s2的范围中,s1和s2的值也会改变,因为s1和s2都指向了这个数组。

而此时如果我们通过s2 = append(s2, 999)来给s2追加一个值,会发生什么? 可见s2已经无法在原来的数组上追加了,此时再追加元素,就会触发扩容机制。

扩容机制:

比如我们有一个容量为2的切片,此时再添加3个元素,我们的容量至少要扩到5,5就是我们的预估容量。

那么我们此时就要判断,如果原来的容量翻倍还是小于这个预估容量,那么我们直接让容量等于预估容量。

否则,看原来切片的容量如果小于1024,那么直接翻倍,如果大于等于1024,每次扩1/4,直到新容量超过所需容量。

image-20220209223741289

第三步就是申请内存,在很多语言中,内存分配不是直接和操作系统交互的,而是和语言自身的内存管理模块交互,而自身的内存管理模块会提前先向操作系统申请一批内存,分成常用的规格管理起来。

当我们申请内存的时候,它会给我们分配足够大且最接近的规格,比如下面的24字节,就会被分配32个字节。

在我们第二步中,我们知道最终的预估容量是5,64位下就需要申请5 * 8 = 40byte字节存放扩容后的底层数组,而实际上申请时会匹配到48字节,48个字节能装48 / 8 = 6个元素(如果是32位操作系统,把前面的8变成4就可以了),这就是我们扩容后的容量了。

image-20220210081435419

此时会创建一个新数组,这个新数组会首先把原数组的内容拿过来,然后在基础上添加元素,再让这个切片指向这个数组。

此时再修改s的内容,不会影响到s2。

image-20220120224510798

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Golang中,切片的扩容是通过内置函数append来实现的。具体实现方法是使用slice结合golang内置方法append进行动态扩容。\[1\]当切片的容量不足以容纳新的元素时,append函数会创建一个新的底层数组,并将原来的元素复制到新的数组中。然后,将新的元素添加到新的数组中,并返回一个新的切片。这样就实现了切片的扩容。切片的底层也是在连续的内存块中分配的,所以切片还能获得索引、迭代以及为垃圾回收优化的好处。\[2\]切片是一个非常小的对象,它是对底层的数组进行了抽象,并且提供了相关的操作方法。它拥有三个字段,分别是指向底层数组的指针、长度和容量。通过对切片再次切片,可以缩小一个切片的大小。\[3\]所以,通过使用append函数和切片的特性,可以实现切片的动态扩容。 #### 引用[.reference_title] - *1* *3* [golang slice扩容机制](https://blog.csdn.net/qq_52696089/article/details/126171790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Golang Slice切片如何扩容](https://blog.csdn.net/moer0/article/details/122933748)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacob_云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值