Golang--数组、切片、映射

news2024/11/5 9:40:56

1、数组

1.1 数组类型

var 数组名 [数组大小]数据类型 

package main
import "fmt"

func main(){
	//1、定义一个数组
	var arr1 [5]int
	arr1[0] = 100
	arr1[1] = 200
	fmt.Println(arr1) //[100 200 0 0 0]
}

1.2 数组的初始化方式

package main
import "fmt"
func main(){
        //第一种:
        var arr1 [3]int = [3]int{3,6,9} //指定类型
        fmt.Println(arr1)
        //第二种:
        var arr2 = [3]int{1,4,7} //自动类型推导
        fmt.Println(arr2)
        //第三种:
        var arr3 = [...]int{4,5,6,7} //自动类型推导
        fmt.Println(arr3)
        //第四种:
        var arr4 = [...]int{2:66,0:33,1:99,3:88} //指定下标初始化+自动类型推导
        fmt.Println(arr4)
}



注意:

  • 定义数组时,声明的长度不同,即使元素的数据类型相同,但整体的数组类型也是不同的,即长度也是属于类型的一部分
  • Go中数组属值类型,在默认情况下是值传递,因此会进行值拷贝,即形参不影响实参
  • 如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
    package main
    import "fmt"
    
    func f(arr *[]int){
    	for i := 0; i < len(*arr); i++ {
    		(*arr)[i] += 10
    	}
    }
    
    func main(){
    	var arr []int = []int{1,2,3,4,5,6,7,8,9,0}
    	f(&arr)
    	fmt.Println(arr) //[11 12 13 14 15 16 17 18 19 10]
    }

1.3 数组内存

package main
import "fmt"
func main(){
        //声明数组:
        var arr [3]int16
        //获取数组的长度:
        fmt.Println(len(arr))
        //打印数组:
        fmt.Println(arr)//[0 0 0]
        //证明arr中存储的是地址值:
        fmt.Printf("arr的地址为:%p",&arr)
        //第一个空间的地址:
        fmt.Printf("arr的地址为:%p",&arr[0])
        //第二个空间的地址:
        fmt.Printf("arr的地址为:%p",&arr[1])
        //第三个空间的地址:
        fmt.Printf("arr的地址为:%p",&arr[2])
}

注意:数组每个空间占用的字节数取决于数组类型
数组优点:可以通过[]下标进行线性访问

1.4 数组遍历

1、使用普通for循环

2、使用for-range循环 (key - value)

package main
import "fmt"

func main(){
	var arr1 = [...]int{1,2,3,4,5,6,7,8,9,10}
	//普通for循环遍历
	for i := 0; i < len(arr1); i++{
		arr1[i] += 10
		fmt.Println(arr1[i]) //11 12 13 14 15 16 17 18 19 20
	}
	fmt.Println("")
	//for-range遍历
	for k,v := range arr1{
		v += 10 //v只是一个副本,对v的修改不会影响arr1的元素
		fmt.Println(arr1[k]) //11 12 13 14 15 16 17 18 19 20
	}
	fmt.Println("")
}

注意:使用for-range时,接收的value变量只是一个副本,副本改变不影响原来arr1数组的元素

 

1.5 二维数组/多维数组

定义:

package main
import "fmt"

func main(){
	//定义二维数组
	var arr [3][4]int = [3][4]int{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
	//遍历二维数组
	for i := 0; i < len(arr); i++ {
		for j := 0; j < len(arr[i]); j++ {
			fmt.Printf("%d ",arr[i][j]) //1 2 3 4 5 6 7 8 9 10 11 12
		}
	}
	fmt.Println("")
	//定义多维数组
	var arr2 [3][2][2][2]int = [3][2][2][2]int{{{{1,2},{3,4}},{{5,6},{7,8}}},{{{9,10},{11,12}},{{13,14},{15,16}}},{{{17,18},{19,20}},{{21,22},{23,24}}}}
	//遍历多维数组
	for i := 0; i < len(arr2); i++ {
		for j := 0; j < len(arr2[i]); j++ {
			for k := 0; k < len(arr2[i][j]); k++ {
				for l := 0; l < len(arr2[i][j][k]); l++ {
					fmt.Printf("%d ",arr2[i][j][k][l]) //1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
				}
			}
		}
	}
}
package main
import "fmt"

func main(){
	//定义二维数组
	var arr [3][4]int = [3][4]int{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
	//遍历二维数组
	for k1,v1 := range arr{
		for k2,v2 := range v1{
			fmt.Printf("arr[%v][%v] = %v\n",k1,k2,v2)
		}
	}
	//定义多维数组
	var arr2 [2][2][2][2]int = [2][2][2][2]int{{{{1,2},{3,4}},{{5,6},{7,8}}},{{{9,10},{11,12}},{{13,14},{15,16}}}}
	//遍历多维数组
	for k1,v1 := range arr2{
		for k2,v2 := range v1{
			for k3,v3 := range v2{
				fmt.Printf("arr2[%v][%v][%v] = %v\n",k1,k2,k3,v3)
			}
		}
	}
}

 

2、切片

2.1 切片

  • 切片(slice)是golang中一种特有的数据类型
  • 数组有特定的用处,但数组长度固定不可变,所以在 Go 语言的代码里并不是特别常见。相对的切片却是随处可见的,切片是一种建立在数组类型之上的抽象,它构建在数组之上并且提供更强大的能力和便捷。
  • 切片(slice)是对数组一个连续片段的引用,所以切片是一个引用类型。这个片段可以是整个数组,或者是由起始和终止索引标识的一些项的子集。需要注意的是,终止索引标识的项不包括在切片内。切片提供了一个相关数组的动态窗口。

切片的语法:
var 切片名 []类型 = 数组的一个片段引用

2.2  切片的内存分析

切片有3个字段的数据:

  • 一个是指向底层数组的指针
  • 一个是切片的长度
  • 一个是切片的容量

 

2.3 切片的定义

方式1:定义一个切片,然后让切片去引用一个已经创建好的数组
方式2:通过make内置函数来创建切片。基本语法: var切片名[type = make([], len,[cap])
(make底层创建一个数组,对外不可见,所以不可以直接操作这个数组,要通过slice去间接的访问各个元素,不可以直接对数组进行维护/操作)
方式3:定一个切片,直接就指定具体数组,使用原理类似make的方式。

注意:
切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用
不能越界

package main
import "fmt"

func main(){
	//方式一:定义一个切片,然后让切片去引用一个已经创建好的数组。
	var arr [5]int = [5]int{1,2,3,4,5}
	var slice []int
	slice = arr[1:3]
	fmt.Println(slice)
	//方式二:通过make内置函数来创建切片。基本语法: var切片名[type = make([], len,[cap])
	// make函数的三个参数:1、切片类型;2、切片的长度;3、切片的容量。
	slice1 := make([]int, 5, 10)
	fmt.Println(slice1)
	fmt.Println(slice1[6])
	//方式三:定义一个切片,直接就指定具体数组。使用原理类似make的方式。
	slice2 := []int{1,2,3,4,5}
	fmt.Println(slice2)
}

 简写方式:

var slice = arr[0:end]  ----> var slice = arr[:end]                //从起始到指定位置

var slice = arr[start:len(arr)]  ---->  var slice = arr[start:]   //从指定位置到末尾

var slice = arr[0:len(arr)]   ----> var slice = arr[:]               //从起始位置到末尾位置

可以对切片继续切片:

package main
import "fmt"

func main(){
	var arr [5]int = [5]int{0,1,2,3,4}
	var slice1 []int = arr[:3]
	var slice2 []int = slice1[1:2]
	slice2[0] = 100
	fmt.Println(arr) //[0 100 2 3 4]
	fmt.Println(slice1) //[0 100 2]
	fmt.Println(slice2) //[100]
}

2.4 切片的遍历

package main
import "fmt"

func main(){
	//定义一个切片
	slice := []int{1,2,3,4,5}
	//方式一:for
	for i := 0; i < len(slice); i++ {
		fmt.Println(slice[i]) //1 2 3 4 5
	}
	//方式二:for-range
	for _,v := range slice{
		fmt.Println(v) //1 2 3 4 5
	}
}

 

2.5 切片的动态增长

package main
import "fmt"

func main(){
	var arr [5]int = [5]int{0,1,2,3,4}
	slice := arr[2:]
	fmt.Println(slice) //[2 3 4 0 0]
	slice = append(slice, 1,2,3,4)
	fmt.Println(slice) //[2 3 4 1 2 3 4]
	slice1 := append(slice,100,200,300)
	fmt.Println(slice1) //[2 3 4 1 2 3 4 100 200 300]
}
package main
import "fmt"
func main(){
        //定义数组:
        var intarr [6]int = [6]int{1,4,7,3,6,9}
        //定义切片:
        var slice []int = intarr[1:4] //4,7,3
        fmt.Println(len(slice))
        slice2 := append(slice,88,50)
        fmt.Println(slice2) //[4 7 3 88 50]
        fmt.Println(slice)
        //底层原理:
        //1.底层追加元素的时候对数组进行扩容,老数组扩容为新数组:
        //2.创建一个新数组,将老数组中的4,7,3复制到新数组中,在新数组中追加88,50
        //3.slice2 底层数组的指向 指向的是新数组 
        //4.往往我们在使用追加的时候其实想要做的效果给slice追加:
        slice = append(slice,88,50)
        fmt.Println(slice)
        //5.底层的新数组 不能直接维护,需要通过切片间接维护操作。
}


可以通过append函数将切片追加给切片:

 

2.6 切片的拷贝

使用函数:copy(目标切片,源切片)

package main
import "fmt"
func main(){
        //定义切片:
        var a []int = []int{1,4,7,3,6,9}
        var b []int = make([]int,10)
        //拷贝:
        copy(b,a) //将a中对应数组中元素内容复制到b中对应的数组中
        fmt.Println(b) //[1 4 7 3 6 9 0 0 0 0]
}

3、映射

映射(map), Go语言中内置的一种类型,它将键值对相关联,我们可以通过键 key来获取对应的值value。 
 

3.1 语法

语法:var 变量名 map[keytype]valuetype


注意:key、value的类型:bool、数字、string、指针、channel 、还可以是只包含前面几个类型的接口、结构体、数组,key不可以是slice、map、function


特点:

  • map集合在使用前一定要make
  • map的key-value是无序的
  • key是不可以重复的,如果遇到重复,后一个value会替换前一个value
  • value可以重复的

3.2 创建方式

package main
import "fmt"
func main(){
        //方式1:
        //定义map变量:
        var a map[int]string
        //只声明map内存是没有分配空间
        //必须通过make函数进行初始化,才会分配空间:
        a = make(map[int]string,10) //map可以存放10个键值对
        //将键值对存入map中:
        a[20095452] = "张三"
        a[20095387] = "李四"
        //输出集合
        fmt.Println(a)
        //方式2:
        b := make(map[int]string)
        b[20095452] = "张三"
        b[20095387] = "李四"
        fmt.Println(b)
        //方式3:
        c := map[int]string{
                20095452 : "张三",
                20098765 : "李四",
        }
        c[20095387] = "王五"
        fmt.Println(c)
}

3.3 map的操作

增加和更新操作:

map["key"]= value , 如果key还没有,就是增加,如果key存在就是修改。

删除操作:
delete(map,"key") , delete是一个内置函数,如果key存在,就删除该key-value,如果key不存在,不操作,但是也不会报错

清空操作:

如果我们要删除map的所有key ,没有一个专门的方法一次删除,可以遍历一下key,逐个删除

或者map = make(...),make一个新的,让原来的成为垃圾,被gc回收

查找操作:

value ,bool = map[key]

value为返回的value,bool为是否返回 ,要么true 要么false 

package main
import "fmt"
func main(){
        //定义map
        b := make(map[int]string)
        //增加:
        b[20095452] = "张三"
        b[20095387] = "李四"
        //修改:
        b[20095452] = "王五"
        //删除:
        delete(b,20095387)
        delete(b,20089546)
        fmt.Println(b)
        //查找:
        value,flag := b[200]
        fmt.Println(value)
        fmt.Println(flag)
}

 获取长度:len函数

 遍历:for-range

package main
import "fmt"
func main(){
	//定义map变量
	//make5个键值对
	var mp map[string]string = make(map[string]string,5)
	mp["string"] = "字符串"
	mp["int"] = "整型"
	mp["float"] = "浮点型"
	mp["bool"] = "布尔型"
	mp["array"] = "数组"
	//遍历map
	for k,v := range mp{
		fmt.Printf("key = %v,value = %v\n",k,v)
	}
}

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

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

相关文章

Android音频进阶之PCM设备创建(九十三)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…

【已解决】C# NPOI如何设置单元格格式

前言 设置单元格格式我们做表格必须要的一步&#xff0c;那么如何对单元格进行设置呢&#xff1f;直接上图看看效果图先&#xff0c;我做的是一个居中然后字体变化的操作&#xff0c;其他的查他的手册即可。 解决方法 直接上代码 IWorkbook excelDoc new XSSFWorkbook();…

系统学习算法:专题一 双指针

题目一&#xff1a; 算法原理&#xff1a; 首先我们可以对这道题目进行题目分类&#xff0c;像这种对数组以某种标准而进行一定的划分的题目&#xff0c;我们统称为数组分块问题&#xff0c;其中使用到的算法就是双指针算法&#xff0c;这里的指针并非真正int*这种&#xff0c…

Python异常检测 - LSTM(长短期记忆网络)

系列文章目录 Python异常检测- Isolation Forest&#xff08;孤立森林&#xff09; python异常检测 - 随机离群选择Stochastic Outlier Selection (SOS) python异常检测-局部异常因子&#xff08;LOF&#xff09;算法 Python异常检测- DBSCAN Python异常检测- 单类支持向量机(…

【双指针】【数之和】 LeetCode 633.平方数之和

算法思想&#xff1a; 双指针枚举i,j&#xff1b;类似三数之和 class Solution { public:bool judgeSquareSum(int c) {long long sum0;vector<int> dp;dp.push_back(0);long long start1;while(sum < c){sum start *start;if(sum>c) break;else dp.push_back(…

前端Nginx的安装与应用

目录 一、前端跨域方式 1.1、CORS(跨域资源共享) 1.2、JSONP(已过时) 1.3、WebSocket 1.4、PostMessage 1.5、Nginx 二、安装 三、应用 四、命令 4.1、基本操作命令 4.2、nginx.conf介绍 4.2.1、location模块 4.2.2、反向代理配置 4.2.3、负载均衡模块 4.2.4、通…

Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口

本示例的目的是介绍如何在vue+openlayers中使用extent,使用feature fit的方式来适配窗口。当加载到页面上几个图形要充分展示在窗口的时候,可以用这种方式来平铺到页面中。 效果图 专栏名称内容介绍Openlayers基础实战 (72篇)专栏提供73篇文章,为小白群体提供基础知识及示…

每日OJ题_牛客_相差不超过k的最多数_滑动窗口_C++_Java

目录 牛客_相差不超过k的最多数_滑动窗口 题目解析 C代码 Java代码 牛客_相差不超过k的最多数_滑动窗口 相差不超过k的最多数_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a; 给定一个数组&#xff0c;选择一些数&#xff0c;要求选择的数中任意两数差的绝对值不超过 …

初始JavaEE篇——多线程(5):生产者-消费者模型、阻塞队列

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 文章目录 阻塞队列生产者—消费者模型生产者—消费者模型的优势&#xff1a;生产者—消费者模型的劣势&#xff1a; Java标准库中的阻…

后端eclipse——文字样式:UEditor富文本编辑器引入

目录 1.富文本编辑器的优点 2.文件的准备 3.文件的导入 导入到项目&#xff1a; 导入到html文件&#xff1a; ​编辑 4.富文本编辑器的使用 1.富文本编辑器的优点 我们从前端写入数据库时&#xff0c;文字的样式具有局限性&#xff0c;不能存在换行&#xff0c;更改字体…

Rust移动开发:Rust在Android端集成使用介绍

Andorid调用Rust 目前Rust在移动端上的应用&#xff0c;一般作为应用sdk的提供&#xff0c;供各端使用&#xff0c;目前飞书底层使用Rust编写通用组件。 该篇适合对Android、Rust了解&#xff0c;想看如何做整合&#xff0c;如果想要工程源码&#xff0c;可以评论或留言有解疑…

推荐一款高级的安装程序打包工具:Advanced Installer Architect

AdvanCEd Installer Architect是一款高级的安装程序打包工具&#xff0c;我们有时候可能用nsis用的多&#xff0c;Advanced Installer Architect也是一款打包工具&#xff0c;有兴趣的朋友也可以试试。有了Advanced Installer Architect你就可以创建MSI打包。 主要功能 *先进的…

关于Linux系统调试和性能优化技巧有哪些?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于Linux系统调试和性能优化技巧的相关内容…

MySQL中,GROUP BY 分组函数

文章目录 示例查询&#xff1a;按性别分组统计每组信息示例查询&#xff1a;按性别分组显示详细信息示例查询&#xff1a;按性别分组并计算平均年龄,如果你还想统计每个性别的平均年龄&#xff0c;可以结合AVG()函数&#xff1a;说明 示例查询&#xff1a;按性别分组统计每组信…

Docker:容器编排 Docker Compose

Docker&#xff1a;容器编排 Docker Compose docker-composedocker-compose.ymlservicesimagecommandenvironmentnetworksvolumesportshealthcheckdepends_on 命令docker compose updocker compose down其它 docker-compose 多数情况下&#xff0c;一个服务需要依赖多个服务&a…

.net Core 使用Panda.DynamicWebApi动态构造路由

我们以前是通过创建controller来创建API&#xff0c;通过controller来显示的生成路由&#xff0c;这里我们讲解下如何不通过controller&#xff0c;构造API路由 安装 Panda.DynamicWebApi 1.2.2 1.2.2 Swashbuckle.AspNetCore 6.2.3 6.2.3添加ServiceAction…

交换机如何实现2.5G网络传输速率和网络变压器有关吗

华强盛电子导读&#xff1a;I19926430038 交换机实现2.5G网络传输速率涉及多个因素&#xff0c;其中包括硬件设计、端口支持、传输介质以及网络协议等。网络变压器在其中扮演了一个重要的角色&#xff0c;但并不是唯一的因素。 1. **硬件设计**&#xff1a;交换机需要有支持2.…

Chrome 130 版本开发者工具(DevTools)更新内容

Chrome 130 版本开发者工具&#xff08;DevTools&#xff09;更新内容 一、网络&#xff08;Network&#xff09;面板更新 1. 重新定义网络过滤器 网络面板获新增了一些过滤条件&#xff0c;这些过滤条件是根据反馈重新设计的&#xff0c;特定于类型的过滤条件保持不变&…

JAVA设计模式之【建造者模式】

1 定义 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 2 类图 产品类&#xff08;Product&#xff09;&#xff1a;表示被创建的复杂…

百度如何打造AI原生研发新范式?

&#x1f449;点击即可下载《百度AI原生研发新范式实践》资料 2024年10月23-25日&#xff0c;2024 NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。本届大会邀请了工业界和学术界的专家&#xff0c;优秀的工程师和产品经理&#xff0c;以及其它行…