数组和切⽚ - 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.mzph.cn/news/92270.shtml

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

相关文章

Java之多线程综合练习小题一

2. 多线程综合练习 练习一:售票 需求: 一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒, 请用多线程模拟卖票过程并打印剩余电影票的数量 代码示例: public class MyThread extends Thread { ​//第一种方式实现多…

Airtool for Mac——高效便捷的系统菜单栏网络工具!

在我们的数字化生活中,对于网络连接的稳定性和速度有着越来越高的需求。为了满足您对网络质量的实时监测和分析的需求,我们向大家介绍一款强大的Mac系统菜单栏网络工具——Airtool! Airtool是一款专为Mac设计的网络工具,它能够提…

Python 笔记07(Mysql数据库基本操作)

一 数据插入 1.1 创建数据列 1.1.1 选择数据库 USE test_data; 1.1.2 插入数据列 ALTER TABLE test_data_info ADD COLUMN stuno INT, ADD COLUMN stuname VARCHAR(255), ADD COLUMN gender VARCHAR(10);1.2 插入具体数据 import MySQLdb# 创建数据库连接 # 主机IP&…

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

任务前期工作: 01. 电脑已安装好VMware Workstation软件; 02.提前下载好Rhel-8.iso映像文件(文件较大一般在9.4GB,建议采用迅雷下载),本人使用的以下版本(地址ed2k://|file|rhel-8.4-x86_64-dvd…

基于PHP+MySQL的养老院管理系统

摘要 随着21世纪互联网时代的兴起,我们见证了人们生活方式的巨大改变。这个时代不仅深刻影响了我们的生活,还改变了我们对信息科学的看法。社会的各个领域都在不断发展,人们的思维也在不断进步,与此同时,信息的需求也与…

rust智能指针

一、智能指针是什么 指针是一个存储内存地址的变量。这个地址指向一些其他数据。 智能指针是一类数据结构&#xff0c;它们类似指针&#xff0c;但是拥有额外的功能。智能指针的概念起源于C。Rust标准库提供了许多智能指针&#xff0c;比如String和Vec<T>&#xff0c;虽…

【React】React组件生命周期以及触发顺序(部分与vue做比较)

最近在学习React&#xff0c;发现其中的生命周期跟Vue有一些共同点&#xff0c;但也有比较明显的区别&#xff0c;并且执行顺序也值得讨论一下&#xff0c;于是总结了一些资料在这里&#xff0c;作为学习记录。 v17.0.1后生命周期图片 初始化阶段 由ReactDOM.render()触发 —…

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

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

用Java打印长方形、平行四边形 、三角形、菱形、空心菱形

今天复习使用嵌套for来完成一些任务&#xff0c;于是想着打印一些图形来练习 思考感悟 长方形 行数 和 每行的星星数嵌套遍历即可 平行四边形 核心&#xff1a;每行空格数总行数-行数 行数空格数132231 三角形 核心&#xff1a;每行星星数2*当前行数-1 行数星星数1123…

【VIM】VIm-plug插件

如何查找需要的插件 https://github.com/mhinz/vim-startify https://github.com/vim-airline/vim-airline https://github.com/Yggdroot/indentLine github.com/w0ng/vim-hybrid github.com/altercationi/vim-colors-solarized guithub.com/morhetz/gruvbox github.com/sc…

kotlin aes 加密解密

文章目录 1. key填充2. 加密3. 解密 1. key填充 aes算法对key的字节数有要求 所以对输入的key要做填充处理 fun fillKey(key: String): ByteArray {val random SecureRandom.getInstance("SHA1PRNG")random.setSeed(key.toByteArray())val generator KeyGenerato…

【2023保研】双非上岸东南网安

个人情况 学校&#xff1a;henu 专业&#xff1a;信息安全 排名&#xff1a;1/66 英语&#xff1a;六级500 竞赛&#xff1a;蓝桥杯PB国一&#xff0c;ISCC国一&#xff0c;密码数学挑战赛国三&#xff0c;还有其他一些省级水奖 论文&#xff1a;一篇EI在投&#xff08;三作通…

C++:红黑树

目录 一、关于红黑树 1、红黑树和AVL树区别 2、红黑树规则 二、红黑树 1、红黑树变色举例 2、红黑树具体情况分析 ①、情况一&#xff1a;只变色 ②、情况二&#xff1a;单旋 变色 ③、情况三&#xff1a;双旋 变色 三、红黑树的模拟实现 一、关于红黑树 1、红黑树…

王道考研计算机网络——传输层

一、传输层概述 复用&#xff1a;发送方不同的应用进程都可以使用同一个传输层的协议来传送数据 分用&#xff1a;接收方的传输层在去除报文段的首部之后能把数据交给正确的应用进程 熟知端口号就是知名端口号0-1023 客户端使用的端口号是动态变化的&#xff0c;不是唯一确定…

某房产网站登录RSA加密分析

文章目录 1. 写在前面2. 抓包分析3. 扣加密代码4. 还原加密 1. 写在前面 今天是国庆节&#xff0c;首先祝福看到这篇文章的每一个人节日快乐&#xff01;假期会老的这些天一直在忙事情跟日常带娃&#xff0c;抽不出一点时间来写东西。夜深了、娃也睡了。最近湖南开始降温了&…

Unity Urp无线延申的网格效果

无线延申的网格 该项目必须是再Urp项目 shader代码实现 Shader "Unlit/infTutorial1" {Properties{_Alpha ("Alpha", Range(0, 0.5)) 0.5}SubShader{Tags{"RenderPipeline""UniversalRenderPipeline""RenderType""…

Pikachu靶场——PHP反序列化漏洞

文章目录 1. PHP反序列化1.1 反序列化代码审计1.2 漏洞防御 1. PHP反序列化 可参考我写的另一篇博客&#xff1a;反序列化漏洞及漏洞复现。 序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串&#xff0c;比如下面是一个对象&#xff1a; class S{publi…

【MySQL】初识数据库

目录 ♫什么是数据库 ♫数据库的分类 ♪关系型数据库 ♪非关系型数据库 ♫显示已有的数据库 ♫创建数据库 ♫删除数据库 ♫使用数据库 ♫数据类型 ♪数值类型 ♪字符串类型 ♪日期类型 ♫创建表 ♫查看表 ♪查看当前数据库下所以表&#xff1a; ♪查看指定表结构&#x…

java多线程相关介绍

1. 线程的创建和启动 在 Java 中创建线程有两种方式。一种是继承 Thread 类并重写其中的 run() 方法&#xff0c;另一种是实现 Runnable 接口并重写其中的 run() 方法。创建完线程对象后&#xff0c;调用 start() 方法可以启动线程。 2. 线程的状态 Java 的线程在不同阶段会处于…

SimpleCG动画示例--汉诺塔动画演示

前言 SimpleCG的使用方法在前面已经介绍了许多&#xff0c;有兴趣的同学如果有去动手&#xff0c;制作一些简单动画应该没多大问题的。所以这次我们来演示一下简单动画。我们刚学习C语言的递归函数时&#xff0c;有一个经典例子相信很多同学都写过&#xff0c;那就是汉诺塔。那…