数组和切⽚ - Go语言从入门到实战

news2024/12/23 3:54:10

数组和切⽚ - Go语言从入门到实战

数组的声明

package main  
  
import "fmt"  
  
func main() {  
 var a [3]int //声明并初始化为默认零值  
 a[0] = 1  
 fmt.Println("a:", a) // 输出: a: [1 0 0]  
  
 b := [3]int{1, 2, 3} //声明同时初始化  
 fmt.Println("b:", b) // 输出: b: [1 2 3]  
  
 c := [2][2]int{{1, 2}, {3, 4}} //多维数组初始化  
 fmt.Println("c:", c) // 输出: c: [[1 2] [3 4]]  
}

数组元素遍历

与其他主要编程语⾔的差异

func TestTravelArray(t *testing.T) {  
    a := [...]int{1, 2, 3, 4, 5} // 这个数组有5个元素  
    for idx, elem := range a {  
        fmt.Println(idx, elem) // 打印索引和元素值  
    }  
}

与其他一些编程语言(如C或Java)不同,Go语言的数组索引是从0开始的。在上面的示例中,第一个元素的索引是0,第二个元素的索引是1,依此类推。
Go语言中的数组是值类型,当你将数组作为参数传递给函数时,会创建一个数组的副本。如果你想在函数内部修改原始数组的元素,需要传递数组的指针。切片则不同,它们是引用类型,传递切片时会共享底层数组。

数组截取、切片

在Go语言中,可以使用切片(slice)来实现数组的截取。切片是对数组的一个连续片段的引用,可以通过指定开始索引和结束索引来定义。
代码示例:

//a[开始索引(包含), 结束索引(不包含)]

a := [...]int{1, 2, 3, 4, 5}  
  
// a[1:2] 截取从索引1到索引2(不包含)的元素,结果为 [2]  
slice1 := a[1:2]  
fmt.Println(slice1) // 输出: [2]  
  
// a[1:3] 截取从索引1到索引3(不包含)的元素,结果为 [2, 3]  
slice2 := a[1:3]  
fmt.Println(slice2) // 输出: [2 3]  
  
// a[1:len(a)] 截取从索引1到数组末尾的元素,结果为 [2, 3, 4, 5]  
slice3 := a[1:len(a)]  
fmt.Println(slice3) // 输出: [2 3 4 5]  
  
// a[1:] 截取从索引1到数组末尾的元素,结果为 [2, 3, 4, 5]  
slice4 := a[1:]  
fmt.Println(slice4) // 输出: [2 3 4 5]  
  
// a[:3] 截取从数组开始到索引3(不包含)的元素,结果为 [1, 2]  
slice5 := a[:3]  
fmt.Println(slice5) // 输出: [1 2]

切片内部结构

切片内部结构

type slice struct {  
    array unsafe.Pointer // 底层数组的指针,指向切片所引用的数组的首个元素的地址。
    len   int            // 切片的长度,即切片当前包含的元素个数。  
    cap   int            // 切片的容量,即从切片的起始位置到底层数组的末尾的元素个数。容量表示了可以在不重新分配内存的情况下,切片可以容纳的元素数量。  
}

切⽚声明

var s0 []int		//声明了一个名为s0的切片,该切片的元素类型为int。s0是一个空切片,长度为0,容量为0。
s0 = append(s0, 1)		//使用append函数将整数1添加到s0切片的末尾。由于s0的容量为0,因此会自动分配内存空间以容纳新元素。s0的长度为1,容量大于1。
s := []int{}		//声明并初始化了一个名为s的切片,该切片的元素类型为int。s是一个空切片,长度为0,容量为0。
s1 := []int{1, 2, 3}		//声明并初始化了一个名为s1的切片,该切片的元素类型为int,并指定了初始元素为1、2和3。此时,s1的长度为3,容量大于或等于3。
s2 := make([]int, 2, 4) 		//使用make函数创建了一个名为s2的切片,该切片的元素类型为int,长度为2,容量为4。s2的前两个元素会被初始化为整数类型的默认零值(即0),而后续的元素则未初始化且不可访问。

 /*
 []type, len, cap
 其中len个元素会被初始化为默认零值,未初始化元素不可以访问
 */

切⽚共享存储结构

切⽚共享存储结构
图片看起来很绕,可以用代码来解释,展示了在Go语言中切片如何共享底层数组的内存。在这个示例中,有一个名为year的字符串切片,它包含了12个月份的名称。然后,通过切片操作,创建了两个新的切片Q2和summer,它们分别引用了year切片的不同片段。


func TestSliceShareMemory(t *testing.T) {
	year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
		"Oct", "Nov", "Dec"}
	Q2 := year[3:6]		
	//Q2 := year[3:6]:创建了一个名为Q2的切片,它引用了year切片从索引3到索引5的元素(不包括索引6)。
	t.Log(Q2, len(Q2), cap(Q2))		
	//输出Q2的内容、长度和容量。此时,Q2的内容为["Apr", "May", "Jun"],长度为3,容量为9(与year切片的容量相同)。
	summer := year[5:8]		
	//创建了一个名为summer的切片,它引用了year切片从索引5到索引7的元素(不包括索引8)。
	t.Log(summer, len(summer), cap(summer))		
	//输出summer的内容、长度和容量。此时,summer的内容为["Jun", "Jul", "Aug"],长度为3,容量为9(与year切片的容量相同)。
	summer[0] = "Unknow"		
	//将summer切片的第一个元素修改为"Unknow"。由于summer和Q2切片共享底层数组的内存,这个修改也会影响到Q2切片对应位置的元素。
	t.Log(Q2)		
	//输出修改后的Q2切片的内容。此时,Q2的内容变为["Unknow", "May", "Jun"]。
	t.Log(year)		
	//输出修改后的year切片的内容。此时,year切片的内容也受到了影响,变为"Jan", "Feb", "Mar", "Apr", "Unknow", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"。
	
}

数组 vs. 切⽚

  1. 容量是否可伸缩:
    • 数组:数组在声明时需要指定元素个数,一旦创建后,其长度和容量都是固定的,无法改变。这意味着数组的大小是固定的,无法根据需要进行扩展或缩小。
    • 切片:切片是对底层数组的一个连续片段的引用,它具有动态大小的特性。切片的长度可以根据需要进行扩展或缩小,而容量也可以根据需要进行增长。这是通过append函数实现的,当切片的长度超过容量时,append函数会自动分配新的底层数组,并将原始数据复制到新的数组中。
  2. 是否可以进行比较:
    • 数组:在Go语言中,数组是值类型,这意味着它们可以进行直接比较。两个数组只有在长度相等且对应位置的元素都相等时才被认为是相等的。
    • 切片:切片是引用类型,它们不可以进行直接比较。切片的比较需要逐个元素进行比较,或者可以使用reflect.DeepEqual函数来进行深度比较。这是因为切片包含了一个指向底层数组的指针,而指针的比较并不是直接比较底层数据的内容。

reflect.DeepEqual函数会递归地比较两个值的结构和具体的元素。对于切片、映射和结构体等复杂数据类型,它会逐个比较它们的元素或字段。

package main  
  
import (  
 "fmt"  
 "reflect"  
)  
  
func main() {  
 slice1 := []int{1, 2, 3}  
 slice2 := []int{1, 2, 3}  
 slice3 := []int{4, 5, 6}  
  
 fmt.Println(reflect.DeepEqual(slice1, slice2)) // 输出: true  
 fmt.Println(reflect.DeepEqual(slice1, slice3)) // 输出: false  
}

学习Go语言主要是多练,多找些代码段写写,不懂可以私聊咨询。

欢迎关注云尔Websites CSDN博客

欢迎进入Golang交流社区

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

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

相关文章

番外6:下载+安装+配置Linux

#########配置Linux---后续 step08: 点击编辑虚拟机设置,选择下载好的映像文件.iso进行挂载; step09: 点击编辑虚拟机选项,选择UEFI启动模式并点击确定; step10: 点击开启虚拟机,选择Install rhel ; 备注&…

架构的未来:微前端与微服务的融合

文章目录 微服务架构简介微前端架构简介微前端与微服务的融合1. 共享服务2. 基于事件的通信3. 统一的身份和认证4. 交付管道的集成 示例:使用微服务和微前端的电子商务平台微服务架构微前端架构融合微服务和微前端 结论 🎉欢迎来到架构设计专栏~架构的未…

【Linux系统编程】僵尸进程与孤儿进程

文章目录 1. 僵尸进程2. 僵尸进程的危害3. 孤儿进程 1. 僵尸进程 上一篇文章进程的状态中最后我们提出了僵尸状态: 为了方便子进程退出后父进程或操作系统获取该进程的退出结果,Linux进程退出时,进程一般不会立即死亡,而是要维持…

【Spring底层原理】BeanFactory的实现

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 容器实现 一、BeanFactory实现的特点1.1 Be…

2023年中国半导体IP行业发展概况及趋势分析:半导体IP的市场空间广阔[图]

半导体指IP指芯片设计中预先没计、验证好的功能模块,处于半导体产业链最上游,为芯片设计厂商提供设计模块。半导体IP按交付方式可分为软核、硬核和固核;按产品类型可分为处理器IP、接口IP、其他物理IP及其他数字IP。 半导体IP分类 资料来源&…

K-Means(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…

ubuntu 18.04 LTS安装opencv 3.4.16 + opencv_contrib 3.4.16

1.下载 opencv 3.4.16 opencv_contrib 3.4.16 其中,opencv_contrib解压后的多个文件夹复制到opencv内、合并 2.安装 参考博文: https://zhuanlan.zhihu.com/p/650792342 https://zhuanlan.zhihu.com/p/87197806 其中 (1)cmake前…

【设计模式】五、原型模式

文章目录 概述示例传统的方式的优缺点原型模式原理结构图-uml 类图 原型模式解决克隆羊问题的应用实例Sheep类实现clone()运行原型模式在 Spring 框架中源码分析 深入讨论-浅拷贝和深拷贝浅拷贝的介绍 小结 概述 示例 克隆羊问题 现在有一只羊 tom,姓名为: tom, 年…

nginx隐藏版本号和标识

1.隐藏版本号:nginx-服务器banner泄漏风险_banner信息泄露_javachen__的博客-CSDN博客 2.隐藏nginx标识 cd /usr/local/nginx-1.24.0/src/corevi nginx.h在第14行 cd /usr/local/nginx-1.24.0/src/httpvi ngx_http_special_response.c在第22,29,36行 cd /usr/local/nginx-1.2…

踩坑日记 uniapp 底部 tabber遮挡住购物车结算

tabbar 被购物车结算遮挡 在小程序上tabbar没有将固定栏遮挡,如果直接调高,浏览器H5页面是对了,但在小程序上面离底部的定位就太高了 原代码 // 底部结算样式.shop-foot {border-top: 2rpx solid #F7F7F7;background-color: #FFF;position: …

法国心理健康平台【Teale】完成1000万欧元A轮融资

来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,位于法国巴黎的心理健康平台【Teale】今日宣布已完成1000万欧元的A轮融资。 本轮融资由Alter Equity和Bpifrance的Digital Venture基金领投,目前的支持者ISAI和Evolem也参与其中。 该公…

ChatGPT的截图识别功能测评:开启图像中的文字与信息的新纪元

文章目录 根据截图,识别菜品根据截图,识别数学公式根据截图生成前端UI代码可视化图像复现案例一案例二 更多可以使用的方向 制作人:川川 辛苦测评,如果对你有帮助支持一下书籍:https://item.jd.com/14049708.html 根据…

spring boot整合常用redis客户端(Jedis、Lettuce、RedisTemplate、Redisson)常见场景解决方案

Java操作redis有三种客户端供选择:Jedis、Lettuce、Redisson。 在实际项目中运用最多的客户端还是Redisson、RedisTemplate;其中RedisTemplate并非是一个新的redis客户端实现,RedisTemplate是Spring Data Redis中提供的封装好的redis操作模板…

闪击笔试题

选择题 ping命令不涉及什么协议? A:DNS B: TCP C: ARP D: ICMP B,ping基于ICMP协议,解析路由会用到ARP和DNS a、b、c三人参加学科竞赛,每个学科按一二三名次给x、y、z分,已知a得22分,b和c得9分&#xf…

进程控制以及相关原语的使用(创建,终止,阻塞,唤醒,切换)

1.基本概念 1.进程控制 进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。 进程控制就是要实现进程状态转换。 2.实现进程控制(原语) 1.原语 原语是一种特殊的程序,它的执行具有原子性。也就是…

初阶数据结构(四)带头双向链表

💓博主csdn个人主页:小小unicorn ⏩专栏分类:数据结构 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 带头双向链表 链表的相关介绍初始化链表销毁链…

一文带你搞懂Redis持久化

Redis持久化 Redis的数据是存储在内存的,当程序崩溃或者服务器宕机,那么内存里的数据就会丢失。所以避免数据丢失的情况,需要将数据保存到其他的存储设备中。 Redis提供两种方式来持久化,分别是 RDB(Redis Database)&#xff1a…

格拉姆角场GAF将时序数据转换为图像并应用于凯斯西储大学轴承故障诊断(Python代码,CNN模型)

1.运行效果: 格拉姆角场GAF将时序数据转换为图像并应用于凯斯西储大学轴承故障诊断(Python代码)_哔哩哔哩_bilibili 环境库 只要tensorflow版本大于等于2.4.0即可运行 同样的模型应用于东南大学轴承数据集:格拉姆角场GAF将时序…

ios telegram iOS telegram二次开发

二次开发方案 一、方案的确定及要实现的效果 首先,最多的信息获取还是官方文档:https://lw.microstrategy.com/msdz/MobileUpdates/941_iOSU5/docs/mergedProjects/mobile_sdk/mobilesdk.htm 在本项目的一小部分,项目需求也是改来改去…

虚拟机中对已经存在的磁盘扩容

如图所示,将虚拟机中已经存在的磁盘进行扩容: 扩展之后重启虚拟机,然后输入命令:lsblk进行查看虚拟机大小;发现这个盘的大小已经改变,如果想要给某个卷组或者逻辑卷进行扩容的话还需要将这个磁盘进行新建分…