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

Go基础——数组、切片、集合

目录

  • 1、数组
  • 2、切片
  • 3、集合
  • 4、范围(range)

1、数组

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。
Go 语言数组声明需要指定元素类型及元素个数,与C语言稍微有所区别:

package mainimport "fmt"func main() {var array1 [10]intarray1 = [10]int{1, 2, 3}              // 未赋值的数组位补0var array2 = [5]string{"a", "b"}       // 未赋值的数组位补空值array3 := [...]float32{1: 1.1, 2: 2.3} // 定义未确定长度的数组,并且给索引1和索引2赋值fmt.Println(array1)fmt.Println(array2)fmt.Println(array3)// 如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小array4 := []int{1, 2, 3}  // 实际为切片fmt.Println(array4)array5 := add(array4) // 将数组作为参数传递fmt.Println(array5)
}func add(arr []int) []int { sum := 0for i := 0; i < len(arr); i++ { // 与python一样,len计算长度sum += arr[i]arr[i] += 1}fmt.Println("re:", sum)return arr
}

注意:在 Go 语言中,数组的大小是类型的一部分,因此不同大小的数组是不兼容的, [5]int 和 [10]int 是不同的类型。形参数组定义长度须与传参保持一致,函数传参时需特别注意!
多维数组与其他语言类似:

package mainimport "fmt"func main() {arrays := [5][5]int{{1, 2, 3, 4, 5},{9, 8, 7, 6, -1},}fmt.Println(arrays)access(arrays)
}
func access(arr [5][5]int) {  // 形参数组定义长度须与传参保持一致// 可通过len得到数组长度,用于不知道数组长度时rows := len(arr)    // 数组行数cols := len(arr[0]) // 数组列数for i := 0; i < rows; i++ {for j := 0; j < cols; j++ {fmt.Print(arr[i][j])}fmt.Print("\n")}
}

数组对比:可判断两个数组的元素是否相同,但两数组长度不相等是不能进行 == 运算

 func contrast() {array1 := [4]int{1, 2, 3, 4}array2 := [4]int{1, 1, 2, 3}fmt.Println(array1 == array2)   // false
}

在这里插入图片描述

2、切片

Go 语言切片是对数组的抽象。Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

// 声明一个未指定大小的数组来定义切片:
var identifier []type

上代码:

package mainimport ("fmt""reflect"
)func main() {array := [5]int{1, 2, 4, 5, 6}fmt.Println("array 类型:", reflect.TypeOf(array)) // array 类型: [5]ints := array[:]fmt.Println("s 类型:", reflect.TypeOf(s)) // s 类型: []intfmt.Println(s)                          // [1 2 4 5 6]// 切片,跟其他语言一样,左闭右开sli1 := array[1:3]sli2 := array[:len(array)-1]sli3 := array[0:]// sli1 := array[1:]// sli1 := array[1:]slic4 := make([]int, 2, 3)  // 长度为2,容量为3的切片fmt.Println(sli1) // [2 4]fmt.Println(sli2) // [1 2 4 5]fmt.Println(sli3) // [1 2 4 5 6]fmt.Println(sli4)  // [0 0]  make创建的切片初始值为0,不等于nilslis()
}func slis() {array1 := [8]int{1, 2, 3, 4}s1 := array1[:]s2 := []int{1, 2, 5, 7}var s3 []int                         // 允许创建nil 空切片fmt.Println("array1-cap: ", cap(s1)) // array1-cap:  8fmt.Println("s2-cap: ", cap(s2))     // s2-cap:  4if s3 == nil {                       // nil是一种特殊的值,表示没有任何指针指向的对象。相当于nullfmt.Println("s3-cap: ", cap(s3)) // 0}array2 := []int{8, 9, 3, 4, 5, 6, 7, 8, 9}fmt.Println("array2-cap: ", array2, cap(array2))array2 = append(array2, 1)fmt.Println("array2-append-cap: ", array2, cap(array2))}

切片可以看做是一个数组,索引、访问都是一样的,并且可以进行增删。
切片除了长度(len),还有容量(cap):容量(capacity)表示切片底层数组中可以容纳的元素数量。切片的容量可以预先分配更多的内存空间,以减少在运行时动态扩展切片的开销。当知道切片可能需要的最大元素数量时,可以通过设置合适的容量来避免频繁的内存分配和数据复制。切片的容量可以用于控制内存的使用。当创建一个切片时,Go语言会根据切片的长度和容量分配相应的内存空间。通过合理设置切片的容量,可以更好地控制内存的使用情况,避免不必要的内存浪费。但是切片的容量并不限制切片的长度,切片的长度可以根据需要动态增长,只要不超过容量的上限。当切片的长度超过容量时,Go语言会自动分配更大的内存空间(一般自动分配为原容量的2倍),并将原有数据复制到新的内存位置。因此,合理地设置切片的容量可以提高程序的性能和内存管理效率,但需要根据具体的应用场景和数据规模来进行权衡和选择。

append()函数:向slice里面追加一个或多个元素,然后返回一个和slice一样类型的slice。通过append也可实现对切片元素的删除。

arr := []int{1, 2}
arr = append(arr, 3, 4, 5, 6, 7, 8, 'a')  // 单引号返回字符ASCII值
fmt.Println(arr)  // [1 2 3 4 5 6 7 8 97]arrs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
arrs = append(arrs[:1], arrs[4:]...)  // 删除索引1到索引3处的元素
fmt.Println(arrs)   // [1 5 6 7 8 9]

copy()函数:用于将源切片中的元素复制到目标切片中。

func copy(dst_slice, src_slice []Type) int

dst_slice是目标切片,src_slice是源切片,Type是切片元素的类型。函数返回为一个整数值,表示实际复制的元素个数(即src和dst的最小长度)

  • dst_slice和src_slice的底层数组必须是相同类型的。例如,不能将一个 []int 类型的切片复制到一个 []string 类型的切片中。
  • copy() 函数不会对切片本身进行初始化,所以在使用 copy() 之前,必须确保目标切片 dst_slice 已经初始化。
  • copy() 不会自动扩容:copy() 函数只会复制dst_slice 切片能容纳的元素数量,如果dst_slice 的容量不足以容纳 src_slice 的所有元素,多余的元素将被丢弃。如果需要将src_slice切片的所有元素复制到dst_slice切片中,并且确保 dst_slice具有足够的容量,需要在复制前先对 dst进行扩容。可以使用 append() 函数来实现切片的扩容,然后再调用 copy() 函数进行复制。
  • copy()函数会将src_slice中的元素逐个复制到dst_slice,不会对切片进行扩容或缩容。
  • copy()函数不会创建新的切片,它只是修改目标切片的内容。
func sli_copy() {sli1 := []int{9, 8, 7, 6, 5, 4}sli2 := make([]int, 6)num := copy(sli2, sli1)fmt.Println(sli2, num) // [9 8 7 6 5 4]  6sli3 := make([]int, 2)  num2 := copy(sli3, sli1)  // copy 到短切片fmt.Println(sli3, num2) // [9 8] 2sli4 := make([]int, len(sli3))_ = copy(sli4, sli3)  // 切片copy后,内存地址不同fmt.Printf("Address: slic3:%p  slic4: %p", sli3, sli4)  // Address: slic3:0xc000016190  slic4: 0xc0000161c0}

注意:当目标切片长度为0时,copy不会生效。如将一个长度为0的切片[]int分配给sli5。sli5的内部数组没有足够的空间来容纳copy操作中src切片中的元素。因此,copy操作不会生效,因为它没有足够的空间去存储复制的数据。

sli5 := make([]int, 0)
_ = copy(sli5, sli3)

3、集合

Go语言中Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以可以像迭代数组和切片那样迭代它。不过,Map 是无序的,遍历 Map 时返回的键值对的顺序是不确定的
在获取 Map 的值时,如果键不存在,返回该类型的零值,例如 int 类型的零值是 0,string 类型的零值是 “”。Map 是引用类型,如果将一个 Map 传递给一个函数或赋值给另一个变量,它们都指向同一个底层数据结构,因此对 Map 的修改会影响到所有引用它的变量。

/* 使用 make 函数 */
map_variable := make(map[KeyType]ValueType, initialCapacity)

其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。

func MapCreate() {map1 := make(map[string]int) // 空mapmap1["a"] = 1                // 与python一样,直接访问键,增加或修改值fmt.Println(len(map1))       // 1map2 := map[string]float32{ // 字面量创建"aa": 1.5,"bb": 2.0,"cc": 3.36,}fmt.Println(map2)// 遍历for k, v := range map2 {fmt.Printf("key=%s, value=%.2f\n", k, v)}// 删除delete(map2, "cc")fmt.Println(map2) // map[aa:1.5 bb:2]
}

delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。如果map中不存在指定的键,那么delete函数什么也不做。

4、范围(range)

range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。
先看切片的range:

	for i, v := range pow {fmt.Printf("索引:%d, 元素:%d \n", i, v)}// 此时遍历得到的是索引for i := range pow {fmt.Printf("%d ", i)}fmt.Printf("\n")// 此时遍历得到的是索引for _, v := range pow {fmt.Printf("%d ", v)}fmt.Printf("\n")// 不需要使用内部元素时lens := 0for range pow {lens++}

集合的range:

func MapRange() {map1 := map[string]int{"num1": 100,"num2": 101,"num3": 102,"num4": 103,}// 键值对遍历for key, vale := range map1 {fmt.Printf("key: %s  value: %d \n", key, vale)}// 只遍历建for key := range map1 {fmt.Printf("key: %s \n", key)}// 只遍历值for _, vale := range map1 {fmt.Printf("value: %d \n", vale)}//range也可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。for i, c := range "go" {fmt.Println(i, c)}// 0 103// 1 111for i, c := range "中文啊" {fmt.Println(i, c)}// 0 20013// 3 25991// 6 21834
}

与切片类似,但比较有意思的是当range范围是字符串时,遍历返回的是字符的Unicode编码值;而且当字符串是中文时,并且采用UTF-8编码时,一个中文占用3字节,如“中文啊”字节序列为:“E4 B8 AD E6 96 87 E5 95 8A”,每个字节对应一个Unicode码点,每三个字节表示一个汉字。上述 i 则是Unicode码点的索引,c则是对应的UTF-8编码。

相关文章:

Go基础——数组、切片、集合

目录 1、数组2、切片3、集合4、范围&#xff08;range&#xff09; 1、数组 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列&#xff0c;这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。 Go 语言数组声明需要指定元素类型及元素个数&#xff0c;与…...

Error: no matching distribution found for tensorflow-cpu==2.6.*

目录 install_tensorflow()安装过程中遇到的问题 查找解决方案过程中&#xff1a; 解决办法&#xff1a; install_tensorflow()安装过程中遇到的问题 在服务器上安装tensorflow时&#xff0c;遇到了一个报错信息&#xff1a; 在网上找到一个类似的错误&#xff08;TensorFlow…...

nginx 进程模型

文章目录 nginx运行模式与进程模式进程模式流程图默认初始化运行模式与进程模式(宏展开)cpu_affinity多CPU绑定合理性判定Nginx的daemon创建&#xff08;os/unix/ngx_daemon.c&#xff09;运行模式、进程模式启动 多进程模式下master处理流程设置进程信号、初始化信号掩码、屏蔽…...

TypeScript - 枚举类型 -字符型枚举

什么是枚举 枚举就是有固定的元素的一个对象。 对象的元素可以直接列举出来。 什么是字符型枚举 字符型枚举&#xff0c;就是元素的值是字符串。 就这么简单。 定义一个我看看 来&#xff0c;让我们实际看一下字符型的枚举。 // 定义字符型枚举 enum COLOR2{RED red,BLUE blu…...

分布式锁-Redis红锁解决方案

一 分布式锁的概念 1&#xff1a;概念 分布式锁&#xff08;多服务共享锁&#xff09; 在分布式的部署环境下&#xff0c;通过锁机制来让多客户端互斥的对共享资源进行访问控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共…...

【Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法】

Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法 错误原因解决办法 错误原因 这是因为ibus输入法有一个快捷键占用了这个终端终结者的快捷键 解决办法 打开命令行输入 ibus-setup进入到如下页面随后将其中的表情注释的快捷键删除即可...

Error: error:0308010C:digital envelope routines::unsupported

Error: error:0308010C:digital envelope routines::unsupported 问题描述&#xff1a; 使用 npm run dev 或者 yarn run dev 时 报错&#xff1a;Error: error:0308010C:digital envelope routines::unsupported PS D:\Project\dlspeed_all\GS-IMS\ruoyi-ui> npm run de…...

RTMP在智能眼镜行业应用方案有哪些?

方案示例 视频直播&#xff1a;智能眼镜通常具有摄像头和显示屏&#xff0c;可以实时拍摄和显示视频。RTMP协议可以用于将智能眼镜拍摄的视频传输到服务器&#xff0c;以便其他用户可以实时观看。远程协作&#xff1a;智能眼镜可以用于远程协作&#xff0c;例如在医疗、建筑等…...

【每日一题】合并两个有序数组

链接奉上&#xff1a;合并两个有序数组 目录 直接合并后排序&#xff1a;思路&#xff1a;代码实现&#xff1a; 双指针思路&#xff1a;代码实现&#xff1a; 直接合并后排序&#xff1a; 思路&#xff1a; 将nums2直接合并到nums1后边&#xff0c;并进行排序 代码实现&…...

MySQL---表的增查改删(CRUD进阶)

文章目录 数据库约束表的设计一对一一对多多对多 新增查询聚合查询分组查询联合查询内连接外连接自连接子查询合并查询 数据库约束 数据库约束就是指&#xff1a;程序员定义一些规则对数据库中的数据进行限制。这样数据库会在新增和修改数据的时候按照这些限制&#xff0c;对数…...

《HelloGitHub》第 91 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…...

jvm线上异常排查流程

1. Linux命令 jps 找出当前运行实例 2. jinfo -flags pid&#xff08;java运行id) 打印出当前设置的jvm内存参数情况 3.jstat -gcutil pid 1000 10 每秒打印一次当前jvm的gc运行情况&#xff0c;一共打印10次 4.将gc日志下载进行分析&#xff1a;到底是因为什么原因导致一直…...

python项目之酒店客房入侵检测系统的设计与实现

项目简介 酒店客房入侵检测系统的设计与实现实现了以下功能&#xff1a; 1、控制台&#xff1a; 控制台是整个系统的首页面。在控制台中&#xff0c;酒店的客房管理人员能够在该页面中查看到当前的空余客房数量、当前在店的客房人数、当前的已用客房数量、当前酒店全部的客房…...

C++ 学习系列 -- 标准库常用得 algorithm function

一 前言 c 标准库中提供了许多操作数据结构&#xff1a;vector、list、deque、map、set 等函数&#xff0c;学习并了解这些常用函数对于我们理解 c 的一些设计模式有着重要的作用。 二 常用的 algorithm function 源码 源代码位置&#xff1a; bits/stl_algo.h 1. accumu…...

[论文笔记]E5

引言 今天又带来一篇文本匹配/文本嵌入的笔记:Text Embeddings by Weakly-Supervised Contrastive Pre-training。中文题目是 基于弱监督对比预训练计算文本嵌入。 本篇工作提出了E5模型(EmbEddings from bidirEctional Encoder rEpresentations)。该模型以带弱监督信号的对…...

k8s 1.28版本:使用StorageClass动态创建PV,SelfLink 问题修复

k8s中提供了一套自动创建 PV 的机制&#xff0c;就是基于 StorageClass 进行的&#xff0c;通过 StorageClass 可以实现仅仅配置 PVC&#xff0c;然后交由 StorageClass 根据 PVC 的需求动态创建 PV。 问题&#xff1a;   使用 k8s 1.28版本&#xff0c;通过 kubectl get pv…...

漏洞复现-dedecms文件上传(CVE-2019-8933)

dedecms文件上传_CVE-2019-8933 漏洞信息 Desdev DedeCMS 5.7SP2版本中存在安全漏洞CVE-2019-8933文件上传漏洞 描述 ​ Desdev DedeCMS&#xff08;织梦内容管理系统&#xff09;是中国卓卓网络&#xff08;Desdev&#xff09;公司的一套基于PHP的开源内容管理系统&#x…...

vue分片上传

<template><div><input type"file" id"input" /><button click"uploadFile">上传</button></div> </template><script lang"ts" setup> let chunkSize1024 * 1024,index0; const upl…...

【大数据Hive】hive 表数据优化使用详解

目录 一、前言 二、hive 常用数据存储格式 2.1 文件格式-TextFile 2.1.1 操作演示 2.2 文件格式 - SequenceFile 2.2.1 操作演示 2.3 文件格式 -Parquet 2.3.1 Parquet简介 2.3.2 操作演示 2.4 文件格式-ORC 2.4.1 ORC介绍 2.4.2 操作演示 三、hive 存储数据压缩优…...

京东平台数据分析(京东销量):2023年9月京东吸尘器行业品牌销售排行榜

鲸参谋监测的京东平台9月份吸尘器市场销售数据已出炉&#xff01; 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年9月&#xff0c;京东吸尘器的销量为19万&#xff0c;环比下滑约12%&#xff0c;同比下滑约25%&#xff1b;销售额为1.2亿&#xff0c;环比下滑约11%&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...