Golang容器:切片

切片slice

动态分配大小连续的空间,切⽚是引⽤类型,当将⼀个切⽚赋值给另⼀个切⽚时,它们引⽤的是相同的底层数组。修改⼀个切⽚的元素会影响到其他引⽤该底层数组的切⽚。切⽚本身不存储元素,⽽是引⽤⼀个底层数组。切⽚的底层数组会在需要时进⾏动态扩展。

数据结构

go 复制代码
type slice struct {
    array unsafe.Pointer //指向底层数组的指针
    len   int //长度
    cap   int //容量
}

切片(slice)本身并非动态数组或数组指针。它内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。

go 复制代码
//切片声明定义
var s[] int
s:=make([]int,0)
//访问切片,i是切片下标,v是元素的值,可以通过i修改切片的值,不能通过v
for i,v:=range s{
	fmt.Println(v)
}
//添加元素
s:=append(s,5,5,5)
//复制
copy( dest Slice, src Slice []T) int

数据被追加到原底层数组。如超出cap限制,由于数组长度的不变性,当涉及底层数组大小无法满足要求时,会创建新的数组。切片容量的扩展是通过底层数组的重建来完成的。append()函数执行时,会首先将传入的切片参数复制一份,生成一个新的切片,

在 Go 1.18 之前的版本中,切片扩容遵循的策略是:对于容量小于 1024 个元素的切片,扩容时容量翻倍;而对于容量超过 1024 的切片,每次扩容增加现有容量的 25%,直至满足需求。

从 Go 1.18 版本开始,Go 语言对切片扩容策略进行了优化,以更高效地处理大容量切片的扩容问题,减少内存分配和拷贝的开销。优化后的扩容策略遵循以下原则:

  1. 容量增长:新容量至少等于原容量加上所需的额外空间,确保扩容满足需求。
  2. 高效内存分配:避免频繁的小幅度扩容,实现内存分配的高效性。

具体优化点包括:

  • 阈值调整:扩容策略的阈值从 1024 字节调整为 256 字节。当切片容量小于 256 字节时,容量增长速度为 2 倍;超过 256 字节后,增长速度减慢至 1.25 倍。
  • 扩容系数平滑过渡 :Go 1.18 引入了新的算法,使得在阈值附近扩容系数能够平滑过渡。具体算法为 (newcap + 3*threshold) / 4,其中 threshold 为 256 字节,这有助于避免扩容系数从 2 倍到 1.25 倍的突然变化。
  • 避免溢出:新策略还包括对潜在溢出的检查,确保在计算新容量时不会发生溢出,避免无限循环,并在必要时将新容量设置为请求的容量大小。
相关推荐
weixin_460443562 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
子兮曰3 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
全栈弄潮儿6 小时前
Python实战第2期: 变量与数据类型
后端·python·agent
Cc.Y6 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python
阿森_dev6 小时前
2027 届毕设选题怎么选:30 个 Java 方向选题的实现难度排序
java·开发语言·spring boot·毕业设计·课程设计
by209996 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
笔墨登场说说6 小时前
flink bin/start-cluster.sh 帮我做成开机启动
开发语言·python
Sarvartha6 小时前
Lambda 表达式和函数式接口
java·开发语言
小白学大数据6 小时前
拼多多反爬对抗实战:Scrapy 中间件化采集架构解析
开发语言·scrapy·中间件·架构