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

数组和切⽚ - 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.xdnf.cn/news/146517.html

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

相关文章

Python3数据科学包系列(二):数据分析实战

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 一:通过read_table函数读取数据创建(DataFrame)数据框 #…

C++指针的使用

文章目录 1.C指针1.1 定义指针1.2 使用指针 2.空指针和野指针2.1 空指针2.2 野指针 3.指针所占空间4.使用const修饰指针4.1 const修饰指针4.2 const修饰常量4.3 const 既修饰指针也修饰常量 5.指针操作数组6.指针做函数参数7.使用指针知识实现冒泡排序 1.C指针 指针其实就是一…

mysql主从同步

原理 概述 将主库的数据变更同步到从库,从而保证主库和从库数据一致 数据备份,失败迁移,读写分离,降低单库读写压力 原理 主数据库设置 docker run --restartalways --name mysql-master -p 3306:3306 -v /home/apps/mysql-…

偏微分方程的人工智能

9 偏微分方程的人工智能 在本节中,我们详细介绍了用于解决偏微分方程(Partial Differential Equations,PDEs)的人工智能领域的进展。我们在第9.1节中概述了PDE建模的一般形式,并阐述了在这个背景下使用机器学习方法的…

竞赛 大数据房价预测分析与可视

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 大数据房价预测分析与可视 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 该项目较为新颖,适合…

JavaScript中如何确定this的值?如何指定this的值?

🎀JavaScript中的this 在绝大多数情况下,函数的调用方法决定了this的值(运行时绑定)。this不能在执行期间被赋值,并且在每次函数呗调用时this的值也可能会不同。 🍿如何确定this的值: 在非严格…

百度交易中台之内容分润结算系统架构浅析

作者 | 交易中台团队 导读 随着公司内容生态的蓬勃发展,内容产出方和流量提供方最关注的“收益结算”的工作,也就成为重中之重。本文基于内容分润结算业务为入口,介绍了实现过程中的重难点,比如千万级和百万级数据量下的技术选型和…

C++八股

1、简述一下C中的多态 在面向对象中,多态是指通过基类的指针或引用,在运行时动态调用实际绑定对象函数的行为,与之相对应的编译时绑定函数称为静态绑定。 静态多态 静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择…

UART相关参数和Modbus协议

温湿度数据和风速风向数据的读取和计算方法 文章目录 温湿度数据和风速风向数据的读取和计算方法1 串行通信数据格式1.1 协议介绍1.2 UART相关参数1.3 UART通信过程 2 USB转串口模块的使用3 串口调试助手的使用3.1 串口控制区3.2 发送控制区3.3 接收控制区 4 GY-39气象信息模块…

在2023年使用Unity2021从Built-in升级到Urp可行么

因为最近在做WEbgl平台,所以某些不可抗力原因,需要使用Unity2021开发,又由于不可明说原因,想用Urp,怎么办? 目录 创建RenderAsset 关联Asset 暴力转换(Menu->Edit) 单个文件…

Object.defineProperty()方法详解,了解vue2的数据代理

假期第一篇,对于基础的知识点,我感觉自己还是很薄弱的。 趁着假期,再去复习一遍 Object.defineProperty(),对于这个方法,更多的还是停留在面试的时候,面试官问你vue2和vue3区别的时候,不免要提一提这个方法…

SLAM从入门到精通(tf的使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在ros的机器人学习过程中,有一件事情是肯定少不了的。那就是坐标系的转换。其实这也很容易理解。假设有一个机器人,它有一个…

Linux文件查找,别名,用户组综合练习

1.文件查看: 查看/etc/passwd文件的第5行 [rootserver ~]# head -5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologi…

性能压力测试的定义及步骤是什么

在今天的数字化时代,软件系统的性能和稳定性对于企业的成功至关重要。为了确保软件在高负载和压力情况下的正常运行,性能压力测试成为了不可或缺的环节。本文将介绍性能压力测试的定义、步骤。 一、性能压力测试的定义和目标 性能压力测试是通过模拟实际…

openGauss学习笔记-86 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署配置

文章目录 openGauss学习笔记-86 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署配置86.1 总体原则86.2 重做日志(MOT)86.3 检查点(MOT)86.4 恢复(MOT)86.5 统计(MOT)86…

USART串口协议

通信接口 •通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统 • 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发 全双工:指通信双方能够同时进行双向通信,一般来说,全双…

阿里云ACP知识点(三)

1、弹性伸缩不仅提供了在业务需求高峰或低谷时自动调节ECS实例数量的能力,而且提供了ECS实例上自动部署应用的能力。弹性伸缩的伸缩配置支持多种特性,例如______,帮助您高效、灵活地自定义ECS实例配置,满足业务需求。 标签、密钥对、 实例RAM…

[docker]笔记-网络故障处理

1、同事在虚拟机上部署docker,发现电脑无法登录虚拟机了。首先ping测是通的,从我电脑继续进行登录测试发现没问题,初步判断是她电脑网络和虚拟机网络之间连接出错。 2、进行虚拟机登录查看,首先使用route -n命令查看路由&#xf…

SpringBoot整合数据库连接

JDBC 1、数据库驱动 JDBC(Java DataBase Connectivity),即Java数据库连接。简而言之,就是通过Java语言来操作数据库。 JDBC是sun公司提供一套用于数据库操作的接口. java程序员只需要面向这套接口编程即可。不同的数据库厂商&…

WPF中的控件

内容控件:label、border Window控件 Label控件 Border控件 内容控件 Button控件 点击取消按钮关闭程序;点击登录按钮打开BorderWindow窗口。 TextBox控件 PasswordBox控件 TextBlock控件 加载窗口时显示TextBlock中的内容 RadioButton控件 CheckBox控件…