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

go中的切片

demo1:切片定义的几种方式

package mainimport "fmt"/*
切片定义的几种方式数组和切片区别:
使用数组传参是值传递,而使用切片传参是引用传递
数组定义好长度之后不可修改,而切片可以理解为动态数组,长度可修改*/func main() {//方法1:直接创建s1 := []string{"1", "2", "3"}fmt.Printf("%T\n", s1)fmt.Println(len(s1))fmt.Println(s1)fmt.Println("--------------------------------------")//方法2:使用make定义,但是需要加上长度,cap可加可不加s2 := make([]string, 3)     //s2:=make([]string, 3,5)   加cap写法fmt.Printf("%T\n", s2)fmt.Println(len(s2))fmt.Println(s2)fmt.Println("--------------------------------------")//方法3:数组变切片arr := [3]string{"1", "2", "3"}s3 := arr[1:2]fmt.Printf("%T\n", s3)fmt.Printf("%T\n", arr)fmt.Println(len(s3))fmt.Println(s3)fmt.Println("--------------------------------------")//方法4:news4 := new([]string)fmt.Printf("%T\n", s4)//fmt.Println(len(s4)) //没有长度fmt.Println(s4) //&[]}

demo2: 切片的基本操作

package mainimport "fmt"/*
切片的基本操作:添加、复制、合并、删除
*/func main() {s1 := []string{"1", "2", "3"}//添加s1 = append(s1, "4", "5")fmt.Println(s1)//复制s2 := []string{}copy(s2, s1)fmt.Println(s2) //这里s2为空,因为没定义长度//拷贝时,目标对象长度为多少就只能复制多少s3 := make([]string, len(s1))copy(s3, s1)fmt.Println(s3)//把两个切片合并s2 = append(s1, s3...) //省略号是规定的参数fmt.Println(s2)//数组中删除元素:先把数组变成切片,再把两个切片合并s4 := s2[:]s4 = append(s2[0:2], s2[4:]...)fmt.Println(s4)
}

demo3: 切片的cap和len

package mainimport "fmt"/*
切片的容量(cap)和长度(len)slice的底层是使用数组实现的,同一个数组的切片会共享内存,但如果切片扩容超过切片的原有容量cap会触发扩容机制,该切片就会自己独立开辟全新内存空间。slice的append扩容问题:扩容阶段因为需要整体开辟全新的内存空间,因此扩容阶段会影响速度。python的list中底层实际上也是数组,也会面临扩容影响速度的问题。python的同一list中可以存不同的数据类型。
*/func main() {//不设置cap时,len和cap大小一致s1 := []string{"1", "2", "3"}fmt.Println(len(s1))    //3fmt.Println(cap(s1))    //3s2 := make([]int, 5)    fmt.Println(len(s2))    //3fmt.Println(cap(s2))    //3s3 := make([]int, 5, 8) //设置了容量capfmt.Println(len(s3))    //5fmt.Println(cap(s3))    //8//通过数组取切片:cap为切片起始位置之后的数组长度s4 := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}s5 := s4[2:5]        fmt.Println(len(s5)) //3fmt.Println(cap(s5)) //8//append函数遇到make问题:如果用make创建切片时定义了长度,append操作会在原有元素之后进行插入。如果没有定义长度,append操作则是对默认元素0进行替换s6 := make([]int, 3)s6 = append(s6, 1)fmt.Println(s6) //[0 0 0 1]s7 := make([]int, 0)s7 = append(s7, 1)fmt.Println(s7) //  [1]}

demo4:切片扩容

案例1:

package mainimport ("fmt"
)func main() {data := [...]int{0, 1, 2, 3, 4, 10: 0} //数组s := data[:2:3]fmt.Println(s)fmt.Println(len(s), cap(s))s = append(s, 100, 200, 300) // 一次 append 三个值,超出 s.cap 限制。fmt.Println(s, data)         // 重新分配底层数组,与原数组无关。fmt.Println(&s[0], &data[0]) // 比对底层数组起始指针。}

从输出结果可以看出:append 后的 s 被重新分配了底层数组(也就是说 s 的底层数组不再是 data,那么修改 s 的值不会再影响 data,它们不再有关联),并把原数组中的值拷贝到新数组中。这是因为超出了原切片的容量。在上例中,如果只追加一个值,则不会超过 s.cap 限制,也就不会重新分配。

切片的自动扩容策略是这样的:(文章:简单说说go语言Slice的底层实现_Liuzhiwang29的博客-CSDN博客 简单说说go语言Slice的底层实现 通过分析源码对这一点提出了质疑)通常 以 2 倍容量 进行扩容,并重新分配底层数组(新底层数组的容量也变大)。如果切片的容量小于 1024 个元素,扩容的时候就翻倍增加容量。一旦元素个数超过 1024 个元素,那么增长因子就变成 1.25 ,即每次增加原来容量的四分之一。注意:扩容扩大的容量都是针对原来的容量而言的,而不是针对原来数组的长度而言的。

所以,在大批量添加数据时,建议 一次性分配足够大的空间 ,以减少内存分配和数据复制开销。或 初始化足够长的 len 属性,改用索引号进行操作。及时释放不再使用的 slice 对象,避免持有过期数组,造成 GC 无法回收。

slice中 cap 重新分配规律:

package mainimport ("fmt"
)func main() {s := make([]int, 0, 1)fmt.Println(s)c := cap(s)                        //计算容量fmt.Println(c)for i := 0; i < 50; i++ {s = append(s, i)               //按理说 append 第2个元素时就超出了cap,这时会重新分配底层数组来扩大capif n := cap(s); n > c {fmt.Printf("cap: %d -> %d\n", c, n)c = n}}}

输出结果:

[]
1
cap: 1 -> 2
cap: 2 -> 4
cap: 4 -> 8
cap: 8 -> 16
cap: 16 -> 32
cap: 32 -> 64

我们可以发现,通常以 2 倍的 cap 重新分配。

提一嘴哈,如果给切片 append 元素时,不超切片容量就没事,操作的还是原数组:

package mainimport ("fmt"
)func main() {data := [...]int{0, 1, 2, 3, 4, 10: 0} //数组s := data[:2:5]                        //将切片容量扩大到5fmt.Println(s)fmt.Println(len(s), cap(s))s = append(s, 100, 200, 300) // 一次 append 三个值,这次没超出 s.cap 限制。fmt.Println(s, data)         fmt.Println(&s[0], &data[0]) // 比对底层数组起始指针}

输出结果:

[0 1]
2 5
[0 1 100 200 300] [0 1 100 200 300 0 0 0 0 0 0]
0xc00004a060 0xc00004a060

案例2:

package mainimport "fmt"//slice的扩容func main() {arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}s1 := arr[2:6]      s2 := s1[3:5]fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n", s1, len(s1), cap(s1)) //2,3,4,5fmt.Printf("s2=%v,len(s2)=%d,cap(s2)=%d\n", s2, len(s2), cap(s2)) //5,6,为什么s2中取到6,是因为slice支持向后扩容//slice的操作:向slice中添加元素s3 := append(s2, 10)s4 := append(s3, 11)s5 := append(s4, 12)fmt.Println("s3,s4,s5:", s3, s4, s5)fmt.Println("arr:", arr)    //为什么没有11,12?   是因为不能超过cap,如果超过cap则会重新分配一个数组进行存储}

相关文章:

go中的切片

demo1:切片定义的几种方式 package mainimport "fmt"/* 切片定义的几种方式数组和切片区别&#xff1a; 使用数组传参是值传递&#xff0c;而使用切片传参是引用传递 数组定义好长度之后不可修改&#xff0c;而切片可以理解为动态数组&#xff0c;长度可修改*/func …...

C++笔记之单例通过GetInstance传递参数

C笔记之单例通过GetInstance传递参数 code review! 文章目录 C笔记之单例通过GetInstance传递参数例1.普通指针的单例例2.结合智能指针和std::call_once例3.编译不通过的错误例子&#xff0c;在GetInstance内不可以使用std::make_shared来创建对象 例1.普通指针的单例 运行 …...

1688API技术解析,实现获得1688商品详情

要实现获得1688商品详情&#xff0c;你需要使用1688 API。1688 API是阿里巴巴旗下的开放平台&#xff0c;它提供了一套丰富的接口&#xff0c;可以让开发者通过编程的方式获取到1688网站上的商品信息。 首先&#xff0c;你需要在阿里开放平台注册一个账号&#xff0c;并创建一…...

【Java 动态数据统计图】动态X轴二级数据统计图思路Demo(动态,排序,动态数组(重点推荐:难)九(131)

需求&#xff1a; 1.有一组数据集合&#xff0c;数据集合中的数据为动态&#xff1b; 举例如下&#xff1a; [{province陕西省, city西安市}, {province陕西省, city咸阳市}, {province陕西省, city宝鸡市}, {province陕西省, city延安市}, {province陕西省, city汉中市}, {pr…...

C#将text文本中的单双行分开单独保存

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 文本的分割1.设定text文件的名称为02.文本导出 文本的分割 1.设定text文件的名称为0 代码如下&#xff1a; using System; using System.Collections.Generic; us…...

深入理解 Go 语言中的 iota

iota是go语言的常量计数器&#xff0c;只能在常量表达式中使用&#xff0c;iota在const关键字出现时将被重置为0&#xff0c;const中每新增一行常量声明将使iota计数一次&#xff0c;可理解为const语句块中的行索引。它会自动递增&#xff0c;从0开始。 修改步长 尽管默认步长…...

【力扣】55、跳跃游戏

var canJump function(nums){let cover 0;for(let i0;i<nums.length;i){if(i<cover){cover Math.max(nums[i]i,cover);if(cover >nums.length-1){return true;}}}}...

个人与公司合作,怎么代开发票?有哪些优惠政策?

《梅梅谈税》专注于企业税务筹划&#xff01;助力企业合理、合规、合法进行节税税收筹划&#xff01; 当下越来越多的个人与公司直接发生业务往来&#xff0c;例如个人给企业提供技术服务&#xff0c;做宣传推广等&#xff0c;业务完成公司给个人支付了相关费用后&#xff0c;…...

什么是计算机视觉,计算机视觉的主要任务及应用

目录 1. 什么是计算机视觉 2. 计算机视觉的主要任务及应用 2.1 图像分类 2.1.1 图像分类的主要流程 2.2 目标检测 2.2.1 目标检测的主要流程 2.3 图像分割 2.3.1 图像分割的主要流程 2.4 人脸识别 2.4.1 人脸识别的主要流程 对于我们人类来说&#xff0c;要想认出身边…...

网易24届内推

【网易】2024届网易互联网秋季校园招聘内推开始啦&#xff01;给你分享我的专属内推邀请函&#xff1a;https://bole.campus.163.com/campus/home?projectId55&type99&isShare1&boleId7b842acc7c2b42db&boleType2&signatured5f2a3dc23bed70777a8be1a14b49…...

redis 应用 4: HyperLogLog

我们先思考一个常见的业务问题&#xff1a;如果你负责开发维护一个大型的网站&#xff0c;有一天老板找产品经理要网站每个网页每天的 UV 数据&#xff0c;然后让你来开发这个统计模块&#xff0c;你会如何实现&#xff1f; img 如果统计 PV 那非常好办&#xff0c;给每个网页一…...

进程的挂起状态

进程的挂起状态详解 当我们谈论操作系统和进程管理时&#xff0c;我们经常听到进程的各种状态&#xff0c;如“就绪”、“运行”和“阻塞”。但其中一个不那么常被提及&#xff0c;但同样重要的状态是“挂起”状态。本文将深入探讨挂起状态&#xff0c;以及为什么和在何时进程…...

idea 链接mysql连不上

打开文件 C:\Program Files\JetBrains\IntelliJ IDEA 2023.2.1\jbr\conf\security\java.security修改内容 搜索&#xff1a;jdk.tls.disabledAlgorithms 修改 链接地址 在链接后面添加 ?useSSLfalse jdbc:mysql://127.0.0.1:3306/db_admin3?useSSLfalse...

Ubuntu 启动出现grub rescue

​ 一&#xff0c;原因 原因&#xff1a;出现 “grub rescue” 错误通常表示您的计算机无法正常引导到操作系统&#xff0c;而是进入了 GRUB&#xff08;Grand Unified Bootloader&#xff09;紧急模式。这可能是由于引导加载程序配置错误、硬盘驱动器损坏或其他引导问题引起…...

go中runtime包里面的mutex是什么?runtime.mutex解析

其实在看go源码的时候&#xff0c;发现除了sync包里有个mutex以外&#xff0c;runtime包里也有一个mutex&#xff0c;这个mutex在runtime很多地方都在用。 这个runtime包里面的mutex的结构如下&#xff1a; 目录: /runtime/runtime2.go 代码&#xff1a; type mutex struct …...

VScode 调试python程序,debug状态闪断问题的解决方法

0. Few words 之前一直在VSCode中debug C和Python的程序没出过闪断的问题&#xff0c;但是最近在另一台电脑上debug&#xff0c;同样的方法&#xff0c;设置launch.json和CMakeList加debug状态等等操作&#xff0c;如我另一篇blog写的一样&#xff0c;可以点这里查看。 但是&a…...

飞桨中的李宏毅课程中的第一个项目——PM2.5的预测

所谓的激活函数&#xff0c;就是李宏毅老师讲到的sigmoid函数 和 hard sigmoid函数 &#xff0c;ReLU函数那些 现在一点点慢慢探索&#xff0c;会成为日后想都做不到的经历&#xff0c;当你啥也不会的时候&#xff0c;才是慢慢享受探索的过程。 有一说一&#xff0c;用chatGP…...

Qt---对话框 事件处理 如何发布自己写的软件

目录 一、对话框 1.1 消息对话框&#xff08;QMessageBox&#xff09; 1> 消息对话框提供了一个模态的对话框&#xff0c;用来提示用户信息&#xff0c;或者询问用户问题并得到回答 2> 基于属性版本的API 3> 基于静态成员函数版本 4> 对话框案例 1、ui界面 …...

【C++】C++ 引用详解 ⑩ ( 常量引用案例 )

文章目录 一、常量引用语法1、语法简介2、常引用语法示例 二、常量引用语法1、int 类型常量引用示例2、结构体类型常量引用示例 在 C 语言中 , 常量引用 是 引用类型 的一种 ; 借助 常量引用 , 可以将一个变量引用 作为实参 传递给一个函数形参 , 同时保证该值不会在函数内部被…...

React原理 - React Reconciliation-下

目录 Fiber Reconciler 【react v16.13.1】 React Fiber需要解决的问题 React Fiber的数据结构 时间分片 Fiber Reconciler 的调度 双缓冲 池概念 小节 练习 Fiber Reconciler 【react v16.13.1】 Fiber 协调 优化了栈协调的事务性弊端引起的卡顿 React Fiber需要解决…...

YOLOv8超参数调优教程! 使用Ray Tune进行高效的超参数调优!

原创文章为博主个人所有,未经授权不得转载、摘编、倒卖、洗稿或利用其它方式使用上述作品。违反上述声明者,本站将追求其相关法律责任。 这篇博文带大家玩点新的东西,也是一直以来困扰大家最大的问题—超参数调优! 之前的 YOLOv5 我使用遗传算法做过很多次调优,实验一跑就…...

JVM运行时数据区

文章目录 JVM内存结构图1、运行时数据区域JDK 1.7JDK 1.81. 线程栈&#xff08;虚拟机栈&#xff09;2. 本地方法栈3. 程序计数器4. 方法区&#xff08;元空间&#xff09;5. 堆6、运行时常量池&#xff08;Runtime Constant Pool&#xff09;7、直接内存&#xff08;Direct Me…...

第七章,相似矩阵及其应用,3-二次型、合同矩阵与合同变换

第七章&#xff0c;相似矩阵及其应用&#xff0c;3-二次型、合同矩阵与合同变换 二次型相关概念二次型二次型的标准形和规范形表示形式 合同矩阵与合同变换定义 合同合同矩阵的性质等价、相似、合同三种关系的对比等价相似合同 玩转线性代数(38)二次型概念、合同矩阵与合同变换…...

css学习7(盒子模型)

1、盒子模型图&#xff1a; Margin(外边距) - 清除边框外的区域&#xff0c;外边距是透明的。Border(边框) - 围绕在内边距和内容外的边框。Padding(内边距) - 清除内容周围的区域&#xff0c;内边距是透明的。Content(内容) - 盒子的内容&#xff0c;显示文本和图像。 <!DO…...

C++笔记之临时变量与临时对象与匿名对象

C笔记之临时变量与临时对象与匿名对象 code review! 文章目录 C笔记之临时变量与临时对象与匿名对象1.C中的临时变量指的是什么&#xff1f;2.C中的临时对象指的是什么&#xff1f;3.C中临时对象的作用是什么&#xff1f;什么时候要用到临时对象?4.给我列举具体的例子说明临…...

缓存技术(缓存穿透,缓存雪崩,缓存击穿)

大家好 , 我是苏麟 , 今天聊一聊缓存 . 这里需要一些Redis基础 (可以看相关文章等) 本文章资料来自于 : 黑马程序员 如果想要了解更详细的资料去黑马官网查看 前言:什么是缓存? 缓存,就是数据交换的 缓冲区 (称作Cache [ kʃ ] ),俗称的缓存就是缓冲区内的数据,是存贮数据的…...

实操教程 | 触发器实现 Apache DolphinScheduler 失败钉钉自动告警

作者 | sqlboy-yuzhenc 背景介绍 在实际应用中&#xff0c;我们经常需要将特定的任务通知给特定的人&#xff0c;虽然 Apache DolphinScheduler 在安全中心提供了告警组和告警实例&#xff0c;但是配置起来相对复杂&#xff0c;并且还需要在定时调度时指定告警组。通过这篇文…...

以“迅”防“汛”!5G视频快线筑牢防汛“安全堤”

近期&#xff0c;西安多地突发山洪泥石流灾害。防洪救灾刻不容缓&#xff0c;为进一步做好防汛工作&#xff0c;加强防洪调度监管&#xff0c;切实保障群众的生命财产安全&#xff0c;当地政府管理部门亟需拓展智能化技术&#xff0c;通过人防技防双保障提升防灾救灾应急处置能…...

jmeter 性能测试工具的使用(Web性能测试)

1、下载 该软件不用安装&#xff0c;直接解压打开即可使用。 2、使用 这里就在win下进行&#xff0c;图形界面较为方便   在目录apache-jmeter-2.13\bin 下可以见到一个jmeter.bat文件&#xff0c;双击此文件&#xff0c;即看到JMeter控制面板。主界面如下&#xff1a; 3、创…...

springboot整合第三方技术邮件系统

springboot整合第三方技术邮件系统&#xff0c;发邮件是java程序的基本操作&#xff0c;springboot整合javamail其实就是简化开发。不熟悉邮件的小伙伴可以先学习完javamail的基础操作&#xff0c;再来看这一部分内容才能感触到springboot整合javamail究竟简化了哪些操作。简化…...