Go语言中底层数组和切片的关系以及数组扩容规则
Go语言中底层数组和切片的关系以及数组扩容规则
demo
package main
import (
"fmt"
)
func main() {
// 声明一个底层数组,长度为10,容量为10
arr := []int {0,1,2,3,4,5,6,7,8,9}
fmt.Printf("[%T]len(arr)=%d,cap(arr)=%d \n",arr,len(arr),cap(arr))
// 声明两个切片,分别取底层数组的[1,4],[7:]
s1 := arr[1:4]
fmt.Printf("[%T]len(s1)=%d,cap(s1)=%d \n",s1,len(s1),cap(s1))
s2 := arr[7:]
fmt.Printf("[%T]len(s2)=%d,cap(s2)=%d \n",s2,len(s2),cap(s2))
// 数组越界指的是超出数组长度,例如下面报:panic: runtime error: index out of range [3] with length 3
//fmt.Println(s1[3])
// s1可以添加元素,添加后s1长度变大,容量不变,同时底层数组被修改
s1 = append(s1, 20)
fmt.Printf("[%T]len(s1)=%d,cap(s1)=%d \n",s1,len(s1),cap(s1))
fmt.Println(arr)
// s2如果需要添加元素,因为容量不够,需要进行扩容,开辟新数组,将原来的7,8,9拷贝过来,再添加一个20,长度为4,容量为6
s2 = append(s2,20)
fmt.Printf("[%T]len(s2)=%d,cap(s2)=%d \n",s2,len(s2),cap(s2))
// 此时修改s2的数组,底层数组arr不再受影响
s2[1] = 10
fmt.Println(arr)
// 容量为什么为6?涉及到数组的扩容规则,举个例子如下:
ints := []int{1,2} // 原容量oldCap =2
ints = append(ints,3,4,5) // 预估容量cap = 5
/*
if oldCap * 2 < cap {
newCap = cap
} else {
if oldLen < 1024 {
newCap = oldCap *2
}else if oldLen >= 1024 {
newCap = oldCap *1.25
}
}
*/
// 上面例子中newCap = 5,int数组所占字节为5*8 = 40,但go语言向内存管理模块向操作系统申请的内存容量却没有40大小的,只有48符合,于是newCap = 48/8 = 6
// go语言内存管理模块是16bytes叠加的,8,16,32,48,64,80,96
// 参考博客:https://www.cnblogs.com/ldaniel/p/8502867.html?utm_source=debugrun&utm_medium=referral
fmt.Printf("[%T]len(ints)=%d,cap(ints)=%d \n",ints,len(ints),cap(ints))
// 例子验证第二种情况
ints2 := []int{1,2}
ints2 = append(ints2,3)
// 此时oldCap * 2 > cap ,满足第二种情况,newCap = 4
fmt.Printf("[%T]len(ints2)=%d,cap(ints2)=%d \n",ints2,len(ints2),cap(ints2))
}
打印输出参考
[[]int]len(arr)=10,cap(arr)=10
[[]int]len(s1)=3,cap(s1)=9
[[]int]len(s2)=3,cap(s2)=3
[[]int]len(s1)=4,cap(s1)=9
[0 1 2 3 20 5 6 7 8 9]
[[]int]len(s2)=4,cap(s2)=6
[0 1 2 3 20 5 6 7 8 9]
[[]int]len(ints)=5,cap(ints)=6
[[]int]len(ints2)=3,cap(ints2)=4
Process finished with exit code 0
Go语言中底层数组和切片的关系以及数组扩容规则的更多相关文章
- cpu的控制单元与语言中的控制逻辑有没有关系?
cpu的控制单元与语言中的控制逻辑有没有关系?
- PHP语言中使用JSON和将json还原成数组
从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 一.json_encode() 1 2 3 4 <?php $arr = ...
- 在PHP语言中使用JSON和将json还原成数组
在之前我写过php返回json数据简单实例,刚刚上网,突然发现一篇文章,也是介绍json的,还挺详细,值得参考.内容如下 从5.2版本开始,PHP原生提供json_encode()和json_deco ...
- ***在PHP语言中使用JSON和将json还原成数组(json_decode()的常见错误)
在之前我写过php返回json数据简单实例,刚刚上网,突然发现一篇文章,也是介绍json的,还挺详细,值得参考.内容如下 从5.2版本开始,PHP原生提供json_encode()和json_deco ...
- 转载:在PHP语言中使用JSON和将json还原成数组
一.json_encode() 1 2 3 4 <?php $arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); e ...
- GO语言总结(3)——数组和切片
上篇博文简单介绍了一下Go语言的基本类型——GO语言总结(2)——基本类型,本篇博文开始介绍Go语言的数组和切片. 一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. ( ...
- Go语言中的切片(十)
go中数组的长度是固定的,且不同长度的数组是不同类型,这样的限制带来不少局限性.于是切片就来了,切片(Slice)是一个拥有相同类型元素的可变长度的序列.它是基于数组类型做的一层封装.它非常灵活,支持 ...
- C++基础 (8) 第八天 数组指针 模板指针 C语言中的多态 模板函数
1昨日回顾 2 多态的练习-圆的图形 3多态的练习-程序员薪资 4员工管理案例-抽象类和技术员工的实现 employee.h: employee.cpp: technician.h: technici ...
- Go - 数组 和 切片(array、slice)
一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. (1)数组的创建 数组有 3 种创建方式: 1) [length]Type 2) [length]Type{value ...
随机推荐
- Vulkan移植GPUImage(五)从P到Z的滤镜
现aoce_vulkan_extra把GPUImage里从P到Z的大部分滤镜用vulkan的ComputeShader实现了,也就是最后一部分的移植,整个过程相对前面来说比较简单,大部分我都是直接复制 ...
- Java中NIO的简单介绍
NIO基本介绍 Java NIO(New IO) 也有人称之为Java non-blocking IO 是从Java1.4版本开始引入的一个新的IO API,可以代替标准的IO API.NIO与原来的 ...
- 1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用
1. 引言 最近在微软Learn平台学习Azure认知服务相关的内容,看到了一个有关"使用自定义视觉对濒危鸟类进行分类"的专题,该专题的主要内容就是使用 Azure Custom ...
- RHEL高级磁盘管理—Stratis
2. Stratis 本地存储管理工具,通过Stratis可以便捷的使用Thin Provisioning.Snapshots.Pool-based的管理和监控等高级存储功能. Stratis 基于x ...
- 开机自动挂载本地yum源-20200402-V0.1
开机自动挂载本地yum源-20200402-V0.1 已下载本地iso /home/Kylin-Server-10-mips64-Release-Build04.08-lic-20200313.iso ...
- Centos7 cache/buff过高处理方法
Centos7 cache/buff过高处理方法 kevinxliu关注0人评论36799人阅读2018-07-26 10:09:59 当linux运行久点,会产生很多不必要的cache或者b ...
- centos7 搭建 nginx web服务 反代理
Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. ...
- SpringBoot基础学习(一) SpringBoot概念、简单案例实现、单元测试及热部署讲解
SpringBoot概念 Spring优缺点分析 Spring优点 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品,无需开发重量级的 ...
- Linux C 进程
进程 UNIX编程手册第6 7章完结 24 25 26 27 28 未完待续,可能等到期末考试结束吧 目录 进程 基础知识 内存分布 命令行参数 环境列表 获得环境 修改环境 非本地跳转 内存分配 在 ...
- .Net RabbitMQ实战指南——RabbitMQ相关概念介绍
什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...