提到切片,我们需要对比数组进行理解:
数组类型的值的长度是固定的,切片类型的值是可变长度的;
数组可以被叫做切片的底层数组,切片可以看作是对数组的某个连续片段的引用;
切片类型是引用类型,数组属于值类型;
len表示长度,cap表示容量。数组的容量等于长度;切片的容量不一定等于长度,切片的容量代表了底层数组的长度。
本文主要围绕切片的容量进行展开。

1)使用make初始化切片
s1:=make([]int,5,8) 指明容量,长度为5,容量是8
s2:=make([]int,5) 不指明容量,那么和长度是一样的,都是5
注意:make是专门用来创建slice,map,channel的值的,返回的是被创建的值,并且可以立即使用;new是申请一小块内存并标记它是用来存放某个值的,返回的是指向这块内存的指针,而且这块内存不会被初始化。

2)直接赋值初始化
s1:= []int{1, 2, 3, 4, 5, 6, 7, 8}
长度和容量都是8

3)在某切片上施加切片
s1:= []int{1, 2, 3, 4, 5, 6, 7, 8}
s2:= s1[3:6]
切片s2的长度为3,容量是5,值为[4,5,6]
说明:切片s2中的索引从0到2,指向的是切片s1及底层数组索引从3到5的值。切片s2和s1的底层数组是一样的,不过切片s2的容量是该底层数组从索引3开始到数组结束的元素个数。
题外话:因为切片s2和s1指向了同样的底层数组,那么需要注意什么呢?
测试代码:

s1:= []int{1, 2, 3, 4, 5, 6, 7, 8}
s2:= s1[3:6]
fmt.Printf("s1: %v (len: %d, cap: %d)\n",s1, len(s1), cap(s1))
fmt.Printf("s2: %v (len: %d, cap: %d)\n",s2, len(s2), cap(s2))s2[0]=100 //s2[0]等同于s1[3]
fmt.Printf("s1: %v (len: %d, cap: %d)\n",s1, len(s1), cap(s1))
fmt.Printf("s2: %v (len: %d, cap: %d)\n",s2, len(s2), cap(s2))

测试打印:
s1: [1 2 3 4 5 6 7 8] (len: 8, cap: 8)
s2: [4 5 6] (len: 3, cap: 5)
s1: [1 2 3 100 5 6 7 8] (len: 8, cap: 8)
s2: [100 5 6] (len: 3, cap: 5)
看到测试代码演示结果,需要注意的是多个切片指向了同一个底层数组,当操作其中一个切片的时候是否会影响到其他指向同一个底层数组的切片。

4)扩容
不会改变原来的切片,而是会生成一个容量更大的切片,然后将原有的元素和新元素一并拷贝到新切片中。一般情况下,可以简单地认为新切片的容量是原切片容量的2倍,当原切片的长度大于等于1024,会是1.25倍。如果我们一次追加的元素过多,以至于使新长度比原容量的2倍还要大,那么新容量就会以新长度为基准。
参考runtime包中slice.go文件里的growslice函数的实现:

newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {newcap = cap
} else {if old.len < 1024 {newcap = doublecap} else {// Check 0 < newcap to detect overflow// and prevent an infinite loop.for 0 < newcap && newcap < cap {newcap += newcap / 4}// Set newcap to the requested cap when// the newcap calculation overflowed.if newcap <= 0 {newcap = cap}}
}

测试代码(这里以切片长度=1024为例,会发现新容量=旧容量*1.25):

s2 := make([]int, 1024)
println(s2)
s2 = append(s2, make([]int, 200)...)
println(s2)

测试结果:
[1024/1024]0xc000055f70
[1224/1280]0xc000058000

参考资料:Go语言核心36讲

golang切片容量计算相关推荐

  1. Golang——切片使用大全(创建、初始化、遍历、截取、修改、添加、切片的copy、切片作为函数参数、切片求和、切片求最大值)

    概念: 切片出现的原因也是因为数组的可操作性不高.切片的长度是不固定的,可以追加数据,可以理解切片是一个动态数组,切片的底层是一个结构体 切片类型(slice)本身并不是动态数组或数组指针.它内部通过 ...

  2. golang 切片的三种简单使用方式及区别

    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...

  3. Android SDCard操作(文件读写,容量计算)

    Android SDCard操作(文件读写,容量计算) android.os.Environment 提供访问环境变量 java.lang.Object android.os.Environment ...

  4. 最大玻尔兹曼分布的mASK信号在AWGN信道下的容量计算

    最大玻尔兹曼分布的mASK信号在AWGN信道下的容量计算_u011852612的博客-CSDN博客

  5. Golang切片的三种简单使用方式及区别

    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...

  6. golang切片转为字符串,字符串转切片

    golang切片转为字符串,字符串转切片 package mainimport ("fmt""strings" )func main() {s := []str ...

  7. DDR5内存条容量计算

    DDR5内存条容量计算 一.理解DDR5通道的变化 二.理解芯片package 三.DDR5 symmetric module容量计算 之前对DDR的一些基础知识进行了总结.最近需要了解DDR5的知识 ...

  8. 锂电池电量百分比计算_锂离子电池容量计算之电压法

    锂离子电池容量计算之电压法 锂离子电池开路电压与电池容量的对应关系分析 先给出一个表格 : 如下 , 百分比是电池的剩余容量 , 右侧是对应的电池的开路电压 (OCV).  100%--- ...

  9. Cris 的 Python 数据分析笔记 05:Pandas 数据读取,索引,切片,计算,列整合,过滤,最值

    Pandas 数据读取,索引,切片,计算,列整合,过滤,最值 文章目录 Pandas 数据读取,索引,切片,计算,列整合,过滤,最值 1. read_csv 函数 2. DataFrame 数据结构的 ...

最新文章

  1. 第4课第4节_Android灯光系统_源码分析_电池灯
  2. How is Attachment property retrieved
  3. centos6上安装mysql8.0版本
  4. 作者:Gopakumar Gopalakrishnan,男,印度科技大学管理学博士,印孚瑟斯技术有限公司高级研究科学家。...
  5. 做购物车系统时利用到得几个存储过程
  6. java随机输出_用java随机输出汉字
  7. JAVA_返回一个数值的相反数的几种方式.
  8. Puppet常用资源使用详解
  9. vue 中引入使用其他字体
  10. VS2015使用FDDB数据库检查人脸检测算法并生成ROC曲线教程
  11. oracle 时间转换 1970,oracle 中将unix/linux时间戳进行转换(转)
  12. 刀刀漫画合集(共享PDF,RAR,UMD版本和语录)
  13. Intel显卡跑ROS与CUDA总结(MacBook Pro 11.6.3)
  14. 关于 iOS 应用申请 Admob 广告时如何获取商店信息
  15. scrapy中代理设置
  16. ethereum扫描区块,获取区块内的交易记录
  17. OpenGL学习笔记——处理键盘输入
  18. 灯具防水等级测试和试验箱
  19. 图的邻接矩阵存储(简单代码实现)
  20. python西瓜视频UP主所有视频封面下载

热门文章

  1. 流传百世的家谱要怎么修?族人:“老规矩”不改还不如不修
  2. php查询数据库无数据判断,php无数据库的内容查询代码 读内容部分
  3. 电脑定时关机怎么设置
  4. Vim 中的 Tab 键与空格键相关配置项详解
  5. python学习第一站:计算机基础
  6. 计算主义质疑(Query Algorithmism)
  7. PromQL到底如何计算rate()的?
  8. ORA-00918: column ambiguously defined错误应对方法
  9. JavaConfig和ApplicationContext.xml实现AOP的转换
  10. linux安卓mac修改,如何伪装或改变android智能手机wifi网卡的mac地址