当前位置: 首页 > news >正文

Go语言容器之数组和切片

  • Go语言的容器分为值类型和引用数据类型

一、数组

1.数组的声明和初始化

(1) 数组声明的语法

  • var 数组变量名 [数组大小]数组类型

  • 举例:

    package main
    import "fmt"func main(){//数组的声明var arr[10]int//打印数组长度fmt.Println("arr的长度为", len(arr))//数组的赋值for i, _ := range arr{arr[i] = i+1}fmt.Println("打印数组")//打印数组for j, w := range arr{fmt.Println(j, arr[j], w)}}
    

    结果:
    在这里插入图片描述

  • 在数组的定义中,若在数组长度的位置出现了"…"省略号,即var 数组变量名[…]数组类型,则表示数组的长度是根据初始化值的个数来决定的。

    package main
    import (
    "fmt"
    )
    func main(){arr1 := [...]int{}arr2 := [...]int{1,2,3,4,5,6,7,8,9}fmt.Println("打印arr1:")for i, _ := range arr1{fmt.Println(arr1[i])}fmt.Println("打印arr2:")for i, _ := range arr2{fmt.Println(arr2[i])}fmt.Printf("arr1的类型为%T:\n",arr1)fmt.Printf("arr2的类型为%T:\n",arr2)
    }
    

    结果:在这里插入图片描述

(2) 比较两个数组是否相等

package mainimport "fmt"func main(){arr1 := [5]int{1,2,3,4,5}arr2 := [...]int{1,2,3,4,5}arr3 := [5]int{0,1,2,3,4}fmt.Printf("arr1==arr2?的结果%v\n",arr1 == arr2)fmt.Printf("arr1==arr3?的结果%v\n",arr1 == arr3)
}

结果:
在这里插入图片描述

2.多维数组

  • 多维数组的语法:var 数组变量名[size1][size2]…[sizen]数组类型

(1) 声明二维数组

package main
import "fmt"func main(){var arr1[4][3]int//声明一个多维数组,大小为4,3arr2 := [4][3]int{{0,1,2},{1,2,3},{2,3,4},{3,4,5}}//声明数组并初始化所有元素arr3 := [4][3]int{1:{0,1,2},2:{1,2,3}}//声明并初始化数组中指定索引的元素arr4 := [4][3]int{1:{0:20},2:{2:30}}//声明并初始化数组中指定元素for i,v := range arr1{fmt.Printf("arr1的结果:")fmt.Println(v)fmt.Printf("arr2的结果:")fmt.Println(arr2[i])fmt.Printf("arr3的结果:")fmt.Println(arr3[i])fmt.Printf("arr4的结果:")fmt.Println(arr4[i])}
}

结果:
在这里插入图片描述

(2) 数组赋值

package mainimport "fmt"func main(){var arr1[2][2]intvar arr2[2][2]intfor i,_ := range arr2{for j, _ := range arr2[i]{arr2[i][j] = i + 1}}arr1 = arr2arr2[0][1] = 10arr2[1][1] = 20for i,v := range arr1{fmt.Printf("arr1的值为:")fmt.Println(v)fmt.Printf("arr2的值为:")fmt.Println(arr2[i])}
}

结果:在这里插入图片描述

二、切片

1.切片概述

  • slice切片就是数组中一段连续的片段的引用。故切片是个引用类型
  • 从数组或者切片生成新的切片:slice[开始位置 : 结束位置]
  • 从数组或者切片中生成新的切片拥有如下特征:
    (1)取出的元素数量为:结束位置 - 开始位置
    (2)取出的元素不包含结束位置对应的索引(左闭右开)。切片最后一个元素是slice[len(slice)]
    (3)当缺省开始位置时,表示从连续区域开头位置到切片结束位置
    (4)当缺省结束位置时,表示从切片开始位置到连续区域末尾位置
    (5)当开始位置和结束位置都缺省时,表示从连续区域开头位置到连续区域末尾位置,即整个连续区域。即表示原有的切片
    (6)当开始位置和结束位置两者都为0时,即空切片。一般用于切片复位
  • 切片举例:
    package mainimport "fmt"func main(){arr := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}fmt.Println("数组arr的值为",arr)fmt.Println("切片arr[0:1]的值为", arr[0:1])fmt.Println("切片arr[2:8]的值为", arr[2:8])fmt.Println("切片arr[4:9]的值为", arr[4:9])fmt.Println("切片arr[5:10]的值为", arr[5:10])fmt.Println("切片arr[5:10]中元素个数为", len(arr[5:10]))fmt.Println("切片最后一个元素arr[len(arr)]的值为",arr[len(arr[4:9])])fmt.Println("切片arr[2:]的值为",arr[2:])fmt.Println("切片arr[:8]的值为",arr[:8])fmt.Println("切片arr[:]的值为",arr[:])
    }
    
    结果:通过结果可以看见,是左闭右开的。在这里插入图片描述
  • 声明新切片的语法:var 切片名[]切片类型
    package mainimport "fmt"func main() {var strSlice []string //声明字符串切片var intSlice []int    //声明整型切片var emptySlice []int{} //声明一个空切片fmt.Println(strSlice, intSlice, emptySlice)fmt.Println("len(strSlice)=", len(strSlice))fmt.Println("len(intSlice)=", len(intSlice))fmt.Println("len(emptySlice)=", len(emptySlice))fmt.Println("strSlice == nil ? =", strSlice == nil)fmt.Println("intSlice == nil ? =", intSlice == nil)fmt.Println("emptySlice == nil ? =", emptySlice == nil)
    }
    
    结果:
    在这里插入图片描述

2.make动态构造切片

  • 若需要动态创建一个切片,则可以使用make()内建函数:make([]切片类型,切片大小,切片容量)
  • 注意:使用make()函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片结果指向已经分配好的区域。设定开始与结束位置不会发生内存分配操作。
    package main
    import "fmt"func main() {slice1 := make([]int, 2, 20)//slice1切片的大小为2,容量为20slice2 := make([]int, 2)//slice2切片的大小为2//slice1和slice2都是预分配了2个元素的切片,只是slice1内部存储空间已经分配了20个,但实际只用了2个fmt.Println("slice1:",slice1)fmt.Println("slice2:",slice2)fmt.Println("len(slice1):",len(slice1))fmt.Println("len(slice2):",len(slice2))
    }
    
    结果:在这里插入图片描述

3.在切片中添加元素

  • 切片的len元素个数并不等于切片的cap容量大小,cap容量扩容是2倍进行扩容的
    package mainimport "fmt"func main() {var slice1 []intfor i:=0; i<20; i++{slice1 = append(slice1, i)fmt.Printf("len:%d, cap:%d, pointer:%p\n", len(slice1), cap(slice1), slice1)}
    }
    
    结果:
    在这里插入图片描述

4.切片复制copy

  • copy(目标切片, 原切片)
    package mainimport "fmt"func main() {arr := [10]int{0,1,2,3,4,5,6,7,8,9}slice1 := arr[2:9]slice2 := []int{10,11,12,13}fmt.Println("复制前:")fmt.Println("slice1=",slice1)fmt.Println("slice2=",slice2)cp1 := copy(slice1,slice2)//将slice2的所有元素复制到slice1cp2 := copy(slice2,slice1)//将slice1中前几个元素复制到slice2中fmt.Println("复制后:")fmt.Println("slice1=",slice1)fmt.Println("slice2=",slice2)fmt.Println("cp1复制的总数为:", cp1)fmt.Println("cp2复制的总数为:", cp2)
    }
    
    结果:
    在这里插入图片描述

5.range关键字循环切片

package main
import "fmt"func main() {arr := [10]int{0,1,2,3,4,5,6,7,8,9}slice1 := arr[2:9]for i,v:=range slice1{fmt.Printf("index:%d, value:%d\n", i, v)}
}

结果:
在这里插入图片描述

6.多维切片

  • 声明方法:var 切片名 [][]…[]切片类型
package mainimport "fmt"func main() {var slice1 [][]intslice1 = [][]int{{0,1},{10,11},{20}}fmt.Println("添加元素前:")for i,v:=range slice1{fmt.Printf("index:%d, value:%d\n", i, v)}slice1[2] = append(slice1[2], 100)//为第三个切片添加值为100的元素fmt.Println("添加元素后:")for i,v:=range slice1{fmt.Printf("index:%d, value:%d\n", i, v)}
}

结果:
在这里插入图片描述

三、数组和切片的区别

  • 数组是数值类型,切片是引用类型
  • 数组的长度是固定的,切片的长度不固定,切片是动态的数组
  • 数组只有长度的概念,切片还有容量(cap)的概念
  • 切片的底层是数组
  • 数组之间可以通过"=="比较,判断两个数组是否有相同元素,但是切片不行,只能和nil进行相等判断
  • 一个零值的切片等于nil,一个nil值的切片并没有底层数组
  • 数组传递给函数的时候,是需要先拷贝再传递;而切片是引用传递,函数内可以直接修改切片的内容

相关文章:

Go语言容器之数组和切片

Go语言的容器分为值类型和引用数据类型 一、数组 1.数组的声明和初始化 (1) 数组声明的语法 var 数组变量名 [数组大小]数组类型 举例&#xff1a; package main import "fmt"func main(){//数组的声明var arr[10]int//打印数组长度fmt.Println("arr的长度为…...

【ROS2知识】humble下使用插件编程

Creating and using plugins (C++) — ROS 2 Documentation: Humble documentation 一、说明 接口编程的好处不言自明,有兴趣的朋友可以看看相关文章。此处在ROS2上进行接口编程,这是个技术难点,如果不能突破,那么许多方面将不能进行,比如:navigation中的costmap_2d包中…...

MySQL 主备一致

MySQL 主备一致主备切换binlog 格式statementrowmixed生产格式循环复制问题主备切换 MySQL 主备切换流程 : 状态 1 : 客户端的读写都直接访问节点 A&#xff0c;而节点 B 是 A 的备库&#xff0c;只将 A 的更新都同步过来 , 并本地执行。来保持节点 B 和 A 的数据是相同当切换…...

玩转CodeQLpy之用友GRP-U8漏洞挖掘

0x01 前言CodeQLpy是作者使用python3实现的基于CodeQL的java代码审计工具&#xff0c;github地址https://github.com/webraybtl/CodeQLpy。通过CodeQLpy可以辅助代码审计人员快速定位代码中的问题&#xff0c;目前支持对SprintBoot的jar包&#xff0c;SpringMVC的war包&#xf…...

GMP调度模型总结

优秀文章 什么是GMP调度模型 Golang的一大特色就是Goroutine。Goroutine是Golang支持高并发的重要保障。Golang可以创建成千上万个Goroutine来处理任务&#xff0c;将这些Goroutine分配、负载、调度到处理器上采用的是G-M-P模型。 什么是Goroutine Goroutine Golang Coro…...

蓝桥回文日期题

题目 题目描述 2020 年春节期间&#xff0c;有一个特殊的日期引起了大家的注意&#xff1a;2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202&#xff0c;恰好是一个回文数。我们称这样的日期是回文日期。 有人表示 20200202 是 “千年…...

【2023】某python语言程序设计跟学第三周内容

目录1.数字类型与操作&#xff1a;整数&#xff1a;浮点数&#xff1a;复数数值运算操作符数字之间关系数值运算函数2.案例&#xff1a;天天向上的力量第一问&#xff1a;1‰的力量第二问&#xff1a;5‰和1%的力量第三问&#xff1a;工作日的力量第四问&#xff1a;工作日的努…...

c++11右值引发的概念

右值引用右值&&左值c11增加了一个新的类型&#xff0c;右值引用&#xff0c;记作&#xff1a;&&左值是指在内存中有明确的地址&#xff0c;我们可以找到这块地址的数据&#xff08;可取地址&#xff09;右值是只提供数据&#xff0c;无法找到地址&#xff08;不…...

MySQL 02 :三层结构、备份删除数据库

MySQL 02 &#xff1a;数据库三层结构-破除MySQL神秘 请添加图片描述 通过golang操作MySQL 创建删除数据库 备份恢复数据库 第一次需要配置环境&#xff0c;否则会报错 报错&#xff1a;mysqldump: Got error: 1045: Access denied for user ‘root’‘localhost’ (using …...

质量员错题合集

项目部质量员根据规范要求认为&#xff0c;接地用的绝缘铜电线规定最小截面为( )mm。4 项目部质量员根据规范要求认为&#xff0c;接地用的绝缘铜电线规定最小截面为4mm&#xff0c;是从( )性能考虑的。机械、 案例中所使用的ZST型闭式喷头的工作压力是( )MPa。1.2 案例中所…...

请教大神们,pmp考试和复习有什么攻略诀窍吗?

PMP考试通过率挺高的&#xff0c;很多考生也是朝九晚五甚至天天加班的打工人&#xff0c;还是有很多人通过了的&#xff0c;我也是下班后和周末才有时间学习的&#xff0c;3A通过&#xff0c;但不是什么考试大神&#xff0c;每天抽出3-4个小时跟着培训机构制定的学习计划学习&a…...

Go语言基础之接口

Go语言基础之接口1.Go语言接口类型2.类型与接口的关系一个类型实现多个接口多种类型实现同一接口3.空接口4.类型断言1.Go语言接口类型 每个接口类型由任意个方法签名组成&#xff0c;接口的定义格式如下&#xff1a; type 接口类型名 interface{方法名1( 参数列表1 ) 返回值列…...

【Go自学第一节】GoLang 数据类型

和Java类型&#xff0c;go拥有多种数据类型&#xff0c;可以把它分为四个大类基础类型、聚合类型、引用类型和接口类型 一、基本数据类型 基本数据类型又可以细分为&#xff1a;数字类型&#xff08;整型、浮点型&#xff09;、布尔类型、字符串类型 整型 Go 的整型分为有符号…...

学习ForkJoin

学习ForkJoin一、普通解决多线程方式1、案例一2、效果图二、ForkJoin一、普通解决多线程方式 1、案例一 大数据量的List问题处理&#xff0c;多线程分批处理&#xff0c;需要解决的问题&#xff1a; 下标越界。线程安全。数据丢失。 private static ThreadPoolExecutor thre…...

System has not been booted with systemd as init system (PID 1). Can‘t operate.

今天想查看防火墙的状态&#xff0c;但是对防火墙的操作还不熟悉&#xff0c;网上搜到的命令是这样的systemctl status firewalld 结果输入之后出现了这样的错误&#xff1a; System has not been booted with systemd as init system (PID 1). Can’t operate. 然后接着去网上…...

使用Endnote自定义参考文献格式

使用Endnote自定义参考文献格式 使用Endnote插入参考文献&#xff0c;若要设置期刊指定格式或自己想要的参考格式&#xff0c;使用EndNote自定义方法&#xff0c;步骤如下。 注&#xff1a;有的期刊会给出EndNote的格式文件&#xff0c;那样直接导入就行。 文章目录使用Endnot…...

jsPlumb Components Crack

jsPlumb Components Crack 为支持Vue 2&#xff0c;所有组件都添加了包装器。 已为所有组件添加了包装器以支持Svelte。 改进了在流程图生成器中编辑多个选定节点。 jsPlumb组件是一组可嵌入的组件&#xff0c;可将可视连接快速集成到网页中。jsPlumb组件基于jsPlumb Toolkit库…...

Java接口

目录 为什么有接口&#xff1f; 接口的定义和使用 注意 接口的基本使用 接口成员的特点 接口和类之间的关系 为什么有接口&#xff1f; 接口就是一种规则 对行为的抽象 接口侧重于行为 接口的定义和使用 接口用于关键字interface来定义public interface 接口名{ }接口不…...

二叉树OJ题目详解

根据二叉树创建字符串 采用前序遍历的方式&#xff0c;将二叉树转换成一个由括号和数字组成的字符串。 再访问每一个节点时&#xff0c;需要分情况讨论。 如果这个节点的左子树不为空&#xff0c;那么字符串应加上括号和左子树的内容&#xff0c;然后判断右子树是否为空&#x…...

#Vue3篇:响应式工具ref()、toRef()、 toRefs()、reactive()的用法和区别

ref() 定义: ref()接收一个普通的Javascript值作为参数&#xff0c;将其转换为响应式对象&#xff08;ref对象&#xff09;。 ref对象有一个.value属性&#xff0c;用于获取和修改之。 参数1: 一个普通的Javascript值作为参数 import { ref } from vue const count ref(0) c…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...