Go语言--语法基础6--基本数据类型--切片类型

Go 语言切片是对数组的抽象。Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活、功能强悍的内置类型切片 ("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

 

切片是一个在 Go 语言中引入的新理念,它有一些特征如下:

 

  • 对数组抽象
  • 数组长度不固定
  • 可追加元素
  • 切片容量可增大

1、定义切片

你可以声明一个未指定大小的数组来定义切片:

 

var identifier []type 

 

切片不需要说明长度。

 

示例

 

var s []int // 定义一个整形大小不定的切片,变量名称 s

 

除此之外,切片还有其他几种定义方式:

 

var (a []int // nil 切片,和 nil 相等,一般用来表示一个不存在的切片b = []int{} // 空切片,和 nil 不相等,一般用来表示一个空的集合c = []int{1, 2, 3} // 有3个元素的切片,len=3,cap=3d = c[:2] // 有2个元素的切片,len=2,cap=3e = c[0:2:cap(c)] // 有2个元素的切片,len=2,cap=3 f = c[:0] // 有0个元素的切片,len=0,cap=3g = make([]int, 3) // 有3个元素的切片,len=3,cap=3 h = make([]int, 2, 3) // 有2个元素的切片,len=2,cap=3 i = make([]int, 0, 3) // 有0个元素的切片,len=0,cap=3 
)

 

本质
切片本身是一个三个字段的数据结构:

 

type SliceHeader struct {Data uintptr // 指向底层数组的指针Len  int     // 切片中元素的个数,通过 len(s) 获取Cap  int     // 切片的容量(不需重新分配内存前,可容纳的元素数量),通过 cap(s) 获取
}

 

区分数组的声明和切片的声明方式
当使用字面量来声明切片时,其语法与使用字面量声明数组非常相似。二者的区别是:如果在 [] 运算符里指定了一个值,那么创建的就是数组而不是切片。只有在 [] 中不指定值的时候,创建的才是切片。

2、切片初始化

s := []int{1, 2, 3}  // 直接初始化切片,[] 表示是切片类型,{1, 2, 3} 初始化值依次是1, 2, 3,其 cap=len=3
s := arr[:]          // 初始化切片 s,是数组 arr 的引用
s := arr[startIndex:endIndex]  // 将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片
s := arr[startIndex:]  // 缺省 endIndex 时将表示一直到 arr 的最后一个元素
s := arr[:endIndex]    // 缺省 startIndex 时将表示从 arr 的第一个元素开始
s1 := s[startIndex:endIndex]  // 通过切片 s 初始化切片 s1
s := make([]int, len, cap)  // 通过内置函数 make() 初始化切片 s,[]int 标识为其元素类型为 int 的切片

3、访问

切片只能访问其长度范围内的内容,通过下标访问:

 

s[i] = 10  // 写操作
v := s[i]  // 读操作

 

迭代方式访问
切片是一个集合,可以通过 range 迭代其中的元素:

 

  1. for 循环方式的迭代

 

var slice = []string{"Red", "Yellow", "Blue", "Green", "Gray"}
// for 循环迭代
for i := 0; i < len(slice); i++ {fmt.Println(i, slice[i])
}

 

  1. range 遍历

 

for index, value := range slice {fmt.Printf("index: %d, value: %s\n", index, value)
}

 

注意

 

  • range 返回的第二个值是对应元素的一份副本,不能用于修改;若要修改则需要通过索引。
  • 迭代方式遍历时,不能对切片进行操作(添加、或删除元素),否则会引发异常。

5、len () 和 cap () 函数

切片是可索引的,并且可以由 len() 方法获取长度。切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

 

示例

 

package main
import "fmt"func main() {var numbers = make([]int, 3, 5)printSlice(numbers)
}func printSlice(x []int) {fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}

 

输出结果

 

len=3 cap=5 slice=[0 0 0]

6、空 (nil) 切片

一个切片在未初始化之前默认为 nil,长度为 0。

 

示例

 

package main
import "fmt"func main() {var numbers []intprintSlice(numbers)if numbers == nil {fmt.Printf("切片是空的")}
}func printSlice(x []int) {fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}

 

输出结果

len=0 cap=0 slice=[]
切片是空的

7、切片的增删改查操作

1. 切片尾部新增元素

var slice []int
// 新增一个元素
slice = append(slice, 1)
// 新增多个元素
slice = append(slice, 1, 2)
// 新增多个元素,切片作为参数,需要使用 ... 运算符来辅助解构切片
var newSlice = []int{1, 2, 3}
slice = append(slice, newSlice...) // ... 不能省略

2. 切片首部新增元素

// 切片首部增加元素
var slice = []int{1, 2}
// 首部增一个元素
slice = append([]int{5}, slice...) 
// 首部增多个元素
var newSlice = []int{5, 6, 7}
slice = append(newSlice, slice...) 

3. 切片中间新增元素

// 切片中间某个位置插入元素
var slice = []int{1, 2, 3}
// 比如需要插入到元素索引 i 后,则先以 i+1 为切割点,把 slice 切割成两半
// 索引 i 前数据:slice[:i+1],索引 i 后的数据:slice[i+1:]
// 然后再把索引 i 后的数据:slice[i:] 合并到需要插入的元素切片中
// 最后再把合并后的切片合并到索引 i 前数据:slice[:i]
// 如在元素索引 1 后增加元素
slice = append(slice[:2], append([]int{6, 7}, slice[2:]...)...)

删除操作

var slice = []int{1, 2, 3, 4, 5, 6}
// 从切片首部删除
slice = slice[1:]
// 从切片尾部删除2个
slice = slice[:len(slice) - 2]
// 从切片中间删除,如从索引为 i,删除2个元素(i+2)
slice = append(slice[:1], slice[3:]...)

其他操作

// 修改元素
var slice = []int{1, 2, 3}
slice[1] = 6// 查找元素
var slice = []int{1, 2, 3}
log.Println("slice[1]=", slice[1])// 试图访问超出其长度的元素就会报错
a := slice[4]  // runtime error: index out of range [4] with length 3
log.Println(a)

课堂练习

使用切片的增删改查功能完成一个简单用户信息录入和维护程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913281.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913281.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​御控物联网综合应用实训平台-物联网系统和实验室实训系统​

在科技飞速发展的今天&#xff0c;物联网技术已渗透到各个领域&#xff0c;成为推动产业升级和创新发展的重要力量。对于职业教育和科研机构而言&#xff0c;搭建一套完善的物联网综合应用实训系统&#xff0c;培养适应时代需求的物联网专业人才&#xff0c;显得尤为迫切。而御…

ElasticSearch中的分片是什么?

大家好&#xff0c;我是锋哥。今天分享关于【ElasticSearch中的分片是什么?】面试题。希望对大家有帮助&#xff1b; ElasticSearch中的分片是什么? 超硬核AI学习资料&#xff0c;现在永久免费了&#xff01; 在 Elasticsearch 中&#xff0c;分片&#xff08;Shard&#x…

基于PHP+MySQL组合开发开源问答网站平台源码系统 源码开源可二次开发 含完整的搭建指南

问答网站成为人们获取知识、交流经验的重要平台。无论是专业领域的疑难解答&#xff0c;还是生活常识的分享探讨&#xff0c;问答网站都发挥着巨大的作用。对于想要搭建问答网站的个人或企业来说&#xff0c;一款优秀的开源问答网站平台源码系统至关重要。今天&#xff0c;我们…

Python工程师面试题集

文章目录一、Python基础二、关键Python库三、Web开发四、并发与性能五、系统设计答案区一、Python基础Python的可变与不可变数据类型有哪些&#xff1f;底层实现原理&#xff1f;Python2与Python3的主要区别解释GIL全局解释器锁及其对多线程的影响装饰器Decorator的作用与实现原…

什么是码率?剪映中如何选择适合的视频码率

在视频编辑过程中&#xff0c;码率&#xff08;Bitrate&#xff09;是一个决定视频画质的关键参数。对于普通用户来说&#xff0c;剪映作为一款功能强大的视频编辑工具&#xff0c;其默认的码率设置直接影响最终导出视频的质量和文件大小。那么&#xff0c;剪映的默认码率是多少…

专题:2025电商营销与AI应用发展趋势报告|附260+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p42834 电商行业在数字经济浪潮中持续演进&#xff0c;2025年呈现出多平台发力、技术驱动增长、消费需求多元等特点。快手和抖音作为国内直播电商的重要阵地&#xff0c;各品类销售表现各有亮点&#xff0c;同时全球电商市场规模稳步…

windows安装stable diffusion

安装git https://git-scm.com/downloads/winclone项目 创建一个文件夹&#xff0c;clone下来stable diffusion webui git网址&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git安装…

Python爬虫 XPath 三方库lxml

前言 XPath是Python爬虫最重要的过滤原始数据的手段之一,是爬虫最核心的技术 是专业抓取HTML页面而生的,基本上只用于抓取HTML页面使用 目录 安装支持XPath三方库lxml XPath代码入门示例 XPath表达式语法 在源代码上面直接获取XPath 安装支持XPath三方库lxml pip instal…

深度学习洪水推演:Python融合多源卫星数据可视化南方暴雨灾情

目录1. 引言&#xff1a;多源卫星融合分析的突破性价值2. 多模态融合架构设计3. 双流程对比分析3.1 单源 vs 多源融合分析3.2 洪水推演核心流程4. 核心代码实现4.1 多源数据融合处理&#xff08;Python&#xff09;4.2 时空洪水推演模型&#xff08;PyTorch&#xff09;4.3 三维…

「日拱一码」016 深度学习常用库——PyTorch

目录 张量操作 创建张量&#xff1a; torch.tensor() &#xff1a;直接从数据创建张量 torch.zeros() &#xff1a;创建全零张量 torch.ones() &#xff1a;创建全一张量 torch.randn() &#xff1a;创建正态分布随机张量 torch.arange() &#xff1a;创建等差序列张量 …

【Qt】QStringLiteral 介绍

QStringLiteral 介绍 QStringLiteral 是 Qt 框架中提供的一个宏&#xff0c;用于在编译时从字符串字面量创建 QString 对象&#xff0c;具有高效和零内存分配的特点。 主要特点 编译时转换&#xff1a;将字符串字面量在编译时转换为 QString 数据&#xff0c;而不是运行时。…

UI前端与数字孪生结合实践探索:智慧物流的货物追踪与配送优化

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;数字孪生重构智慧物流的技术范式在物流行业数字化转型的浪潮中&#xff0…

Java创建型模式---工厂模式

工厂模式基础概念 工厂模式是一种创建型设计模式&#xff0c;其核心思想是将对象的创建和使用分离。通过使用工厂模式&#xff0c;可以将对象创建逻辑集中管理&#xff0c;提高代码的可维护性和可扩展性。在 Java 中&#xff0c;工厂模式主要分为三种类型&#xff1a; 简单工…

分布式定时任务:xxl-job

基础 XXL - Job采用的是调度中心&#xff08;Scheduler&#xff09;与执行器&#xff08;Executor&#xff09;分离的架构设计&#xff0c;这种设计带来了诸多优势&#xff0c;比如高可用性、可扩展性以及便于分布式部署等。 1. 调度中心&#xff08;XXL - Job Admin&#xf…

易语言实现钉钉PC端高频率链接批量打开系统

易语言实现钉钉PC端高频率链接批量打开系统 一、需求分析与技术方案 核心需求: 在钉钉PC端私聊消息中嵌入特殊格式链接用户点击后通过自定义协议唤醒本地程序支持每分钟处理10万次请求的批量操作实现链接的批量生成和管理技术方案: #mermaid-svg-AYoMWYQQf71dlyEF {font-fa…

MyBatis如何实现动态数据源切换?

大家好&#xff0c;我是锋哥。今天分享关于【MyBatis如何实现动态数据源切换&#xff1f;】面试题。希望对大家有帮助&#xff1b; MyBatis如何实现动态数据源切换&#xff1f; 超硬核AI学习资料&#xff0c;现在永久免费了&#xff01; 在MyBatis中实现动态数据源切换&#…

实践篇:14-构建 Node.js 应用程序镜像

背景介绍 Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff0c;以其事件驱动、非阻塞 I/O 模型而闻名&#xff0c;广泛用于构建后端服务和前端应用。 Node.js 的特点使其非常适合容器化部署&#xff1a; 轻量级运行时&#xff1a;相比传统后端语言&#xf…

Spring Cloud 微服务(链路追踪与日志聚合)

&#x1f4cc; 摘要 在微服务架构中&#xff0c;随着服务数量的增加和调用关系的复杂化&#xff0c;传统的日志记录方式已经无法满足对系统运行状态的全面掌控。如何快速定位异常请求、分析服务调用耗时、追踪完整链路成为运维和开发人员面临的核心挑战。 为此&#xff0c;Sp…

PADS交互式布局

PADS的交互式布局通过原理图与PCB的双向联动大幅提升设计效率。在原理图中框选电路模块时&#xff0c;PCB视图将自动高亮对应元件组并生成可移动簇&#xff0c;拖动时保持模块内部相对位置不变。布局过程中启用实时推挤功能&#xff08;Placement Shoving&#xff09;&#xff…

类图+案例+代码详解:软件设计模式----原型模式

5、原型模式 通过复制现有对象来创建新对象&#xff0c;避免从零开始构建&#xff0c;就像 “复印文件” 一样。 克隆的核心是复用现有对象状态 用 克隆熊猫 举例&#xff0c;秒懂原理 假设你有一只熊猫对象&#xff08;属性&#xff1a;名字、年龄、毛色&#xff09;&#…