当前位置: 首页 > 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需要解决…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...