Go语言-数组和切片有什么异同?

slice 的底层数据是数组,slice 是对数组的封装,它描述一个数组的片段。两者都可以通过下标来访问单个元素。

数组是定长的,长度定义好之后,不能再更改。在 Go 中,数组是不常见的,因为其长度是类型的一部分,限制了它的表达能力,比如 [3]int 和 [4]int 就是不同的类型。

而切片则非常灵活,它可以动态地扩容。切片的类型和长度无关。

数组就是一片连续的内存, slice 实际上是一个结构体,包含三个字段:长度、容量、底层数组。

// runtime/slice.go
type slice struct {array unsafe.Pointer // 元素指针len   int // 长度 cap   int // 容量
}

slice 的数据结构如下:
在这里插入图片描述
注意,底层数组是可以被多个 slice 同时指向的,因此对一个 slice 的元素进行操作是有可能影响到其他 slice 的。

【引申1】
[3]int 和 [4]int 是同一个类型吗?

不是。因为数组的长度是类型的一部分,这是与 slice 不同的一点。

【引申2】
下面的代码输出是什么?

说明:例子来自雨痕大佬《Go学习笔记》第四版,P43页。这里我会进行扩展,并会作图详细分析。

package mainimport "fmt"func main() {slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}s1 := slice[2:5]s2 := s1[2:6:7]s2 = append(s2, 100)s2 = append(s2, 200)s1[2] = 20fmt.Println(s1)fmt.Println(s2)fmt.Println(slice)
}

结果:

[2 3 20]
[4 5 6 7 100 200]
[0 1 2 3 20 5 6 7 100 9]

s1 从 slice 索引2(闭区间)到索引5(开区间,元素真正取到索引4),长度为3,容量默认到数组结尾,为8。
s2 从 s1 的索引2(闭区间)到索引6(开区间,元素真正取到索引5),容量到索引7(开区间,真正到索引6),为5。

在这里插入图片描述
接着,向 s2 尾部追加一个元素 100:

s2 = append(s2, 100)
s2 容量刚好够,直接追加。不过,这会修改原始数组对应位置的元素。这一改动,数组和 s1 都可以看得到。

在这里插入图片描述
再次向 s2 追加元素200:

s2 = append(s2, 100)
这时,s2 的容量不够用,该扩容了。于是,s2 另起炉灶,将原来的元素复制新的位置,扩大自己的容量。并且为了应对未来可能的 append 带来的再一次扩容,s2 会在此次扩容的时候多留一些 buffer,将新的容量将扩大为原始容量的2倍,也就是10了。

在这里插入图片描述
最后,修改 s1 索引为2位置的元素:

s1[2] = 20
这次只会影响原始数组相应位置的元素。它影响不到 s2 了,人家已经远走高飞了。

在这里插入图片描述
再提一点,打印 s1 的时候,只会打印出 s1 长度以内的元素。所以,只会打印出3个元素,虽然它的底层数组不止3个元素。

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

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

相关文章

【开源软件治理】MITRE : 开源软件

定义: 开源软件(OSS)是一种商业软件,只需同意遵守附带的 OSS 许可证即可获得全部所有权,无需立即进行第三方验证。同意 OSS 许可证允许个人、公司或政府实体根据需要尽可能频繁和广泛地复制、分发和运行 OSS 应用程序&…

现代C++新特性 扩展的聚合类型(C++17 C++20)(PC浏览效果更佳)

文字版PDF文档链接:现代C新特性(文字版)-C文档类资源-CSDN下载 1.聚合类型的新定义 C17标准对聚合类型的定义做出了大幅修改,即从基类公开且非虚继承的类也可能是一个聚合。同时聚合类型还需要满足常规条件。 1.没有用户提供的构造函数。…

Django_模型类详解(七)

目录 一、定义属性 字段类型 选项 二、查询集 两大特性 查询集的缓存 限制查询集 三、条件查询 条件运算符 1) 查询相等 2) 模糊查询 3) 空查询 4) 范围查询 5) 比较查询 6) 日期查询 F对象 Q对象 聚合函数 四、关联查询 通过对象执行关联查询 通过模型类执…

Squid 缓存代理(一)---原理及搭建(传统代理、透明代理)

前言 Squid 是 Linux 系 统 中 最 常 用 的 一 款 开 源 代 理 服 务 软 件 ( 官 方 网 站 为 http://www.squid-cache.org),可以很好地实现 HTTP 和 FTP,以及 DNS 查询、SSL 等应用的缓存代理。缓存代理作为应用层的代理服务软件…

Python学习笔记-基于socket基础的http服务端程序

通过HTTP协议可以进行通信可以规范化的进行网络间通信。下面技术第一个http服务器小程序。简单的记录第一个试手程序。 1.http通信的基本流程 整个流程对应四层网络架构:应用层、传输层、网络层、链路层。有的部分已经封装,不需要我们再行处理。 2.服务…

SAR ADC version2 ——ADC背景介绍

目录: ADC常用指标分类 静态性能:微分非线性:DNL 积分非线性:INL 仿真测试DNL:(码密度法)(code density&…

1.Git使用技巧-常用命令1

Git使用技巧-常用命令 文章目录 Git使用技巧-常用命令一、git 创建仓库demo 二、本地仓库常用命令提交详解git commitgit commit --amend 三、 推送到远程分支git push 总结参考 一、git 创建仓库 创建远端仓库: git init – bare // 创建远端裸仓库; 远…

哈工大计算网络课程数据链路层详解之:数据链路层服务

哈工大计算网络课程数据链路层详解之:数据链路层服务 在介绍完网络层的实现功能和协议之后,接下来我们继续介绍网络层的下一层:数据链路层。 本节首先对数据链路层的功能和所提供的服务进行概述。 如下图示例网络所示,标红色的部…

18.Lucas-Kanade光流及OpenCV中的calcOpticalFlowPyrLK

文章目录 光流法介绍OpenCV中calcOpticalFlowPyrLK函数补充reference 欢迎访问个人网络日志🌹🌹知行空间🌹🌹 光流法介绍 光流描述了像素在图像中的运动,就像彗星☄划过天空中流动图像。同一个像素,随着时…

【三】部署zabbix-proxy代理服务器和高可用,以及监控windows系统和java应用

zabbix代理服务器和高可用 1.部署zabbix代理服务器1.1 代理端zabbix-proxy配置1.2 客户端zabbix-agent配置1.3 zabbix-proxy总结 2. 部署Zabbix高可用集群2.1 主节点zabbix-server配置2.2 备节点zabbix-server配置2.3 客户端zabbix_agent配置2.4 Zabbix高可用集群总结 3.Zabbix…

【uniapp开发小程序】实现读取手机剪切板第一条,识别并以姓名/手机号/收货地址格式输出

效果图&#xff1a; 完整代码&#xff1a; <template><view class""><text>测试</text><view click"pasteContent()" class"content">点击此处可快速识别 您的收货信息</view></view> </templat…

WAIC2023记录

汤晓鸥 学生与工作&#xff1a; 微软布局大模型方向