当前位置: 首页 > news >正文

【go】slice原理

slice包含3个部分:
1.内存的起始位置
2.切片的大小(已经存放的元素数量)
3.容量(可以存放的元素数量)

使用make初始化切片会开辟底层内存,并初始化元素值为默认值,如数字为0,字符串为空

使用New初始化切片不会开辟底层数组,而且返回的是指向类型的指针

不同的切片可以公用底层数组,如

arr := []int{1, 2, 3, 4, 5, 6, 7, 8}arr1 := arr[1:5]

这里arr1是从数组下标1~4的引用(左闭右开),它的大小为4,容量到底层数组的结尾,即7。
当arr或arr1修改元素的时候,底层数组受影响,同时作用于两个arr和arr1两个变量。
又或者arr1使用append添加元素的时候,由于切片的容量为7,所以会直接在底层数组上覆盖原本的元素。但是如果append操作需要扩容的时候,并不会在原有的底层数组上直接往后加元素,而是复制出来一份到新的内存上,所以不会影响原底层数组。

扩容规则:
1.预估元素个数
如果扩容前的容量翻倍依旧不能满足所需,则直接扩容到所需的容量。
否则,如果元素个数<1024则直接翻倍,如果>=1024则扩容1.25倍。
否则,先判断元素个数<256则直接翻倍,如果大于等于256会根据const threshold = 256;newcap += (newcap + 3*threshold ) / 4这个公式进行容量预估。如果不能满足所需容量则再次根据此公式循环。相比与之前的1.25倍的容量扩容,这个公式提供了一个过度曲线,小切片更趋向于2倍,大切片更趋向于1.25倍。
2.实际分配内存
程序申请内存并不是需要多少就直接能拿到多少,而是从操作系统中拿到满足所需容量的最小内存。比如程序会预先从操作系统中申请16,32,48等等不同规格的内存,然后在根据所需容量占据的内存拿到最合适的内存。

例子:
[]int数组{1,2},在执行append时arr = append(arr, 3, 4, 5),根据1,判断需要的容量为5,64位系统下一个int占64位,即8字节。预估需要的内存为5*8=40字节。但是程序分配内存不会直接分配40字节的内存,而是找到满足条件的最小规格内存48字节。48字节可以容纳的元素个数位48/8=6,所以上述实append操作实际上扩容后的容量为6。

http://www.lryc.cn/news/15274.html

相关文章:

  • 【数据库】MySQL概念知识语法-基础篇(DQL),真的很详细,一篇文章你就会了
  • 博客界的至高神:属于自己的WordPress网站,你值得拥有!
  • 操作系统(day13)-- 虚拟内存;页面分配策略
  • SQL零基础入门学习(四)
  • 19岁就患老年痴呆!这些前兆别忽视!
  • 【C++】thread|mutex|atomic|condition_variable
  • 学成在线项目笔记
  • FreeRTOS队列
  • rancher2安装nfs-subdir-external-provisioner为PVC/PV动态提供存储空间(动态分配卷)
  • 1.JAVA-JDK安装
  • Java必备小知识点4——数据类型、数组、位运算符
  • 麦克风分类汇总
  • 九龙证券|机制改革激发转融券活力 全面注册制释放两融展业新空间
  • 6——JVM调优工具详解及调优实战
  • AcWing语法基础课笔记 第八章 C++ STL 第九章 位运算与常用库函数
  • Qt中的多线程
  • React-Hooks怎样封装防抖和节流-面试真题
  • 算法训练营 day51 动态规划 打家劫舍系列
  • 【蓝桥集训】第六天——递归
  • react源码中的hooks
  • 038.Solidity入门——25调用其他合约的方法
  • Revit项目浏览器的标准设置应用和快速视图样板?
  • 安装MQTT Server遇到报错“cannot verify mosquitto.org‘s certificate”,该如何解决?
  • 程序员如何向架构师转型?看完就明白该怎么做了
  • Flask入门(9):蓝图
  • 跑步戴哪种耳机好,最适合运动跑步的蓝牙耳机
  • 微信小程序实现瀑布流布局
  • 2023最新网络工程师HCIA-Datacom“1000”道题库,光速刷题拿证
  • [蓝桥杯] 递归与递推习题训练
  • 领航智能汽车信息安全新征程 | 云驰未来乔迁新址