九、Go语言快速入门之map

news2024/11/6 21:46:42

文章目录

    • Map
      • :one: 使用`Map`
        • :star2: 声明和初始化
        • :star2: `map`容量
        • :star2: 用切片作为`map`的值
      • :two: 测试键值对是否存在及删除元素
      • :three: `For`-`range`
      • :four: `map`类型的切片
      • :five: map的排序
      • :six:将map的健和值对调

📦 使用版本为1.21.5

Map

在很多编程语言中都有map的存在,在Python中叫做字典,在java中也叫map,它的存储形式是key-value

1️⃣ 使用Map

🌟 声明和初始化

⭐️ map是引用类型,可以使用如下方法来声明一个map,注意只是声明一个map,而不是初始化

可以使用make来分配内存,不要使用new如果你错误的使用 new() 分配了一个引用对象,你会获得一个空引用的指针,相当于声明了一个未初始化的变量并且取了它的地址

func main() {
	var map1 map[string]int     //声明一个map,基础方法 其中string为key的类型,int为value的类型
	map2 := make(map[string]int) //使用make这里是初始化map了
    map3 := map[string]int{"one":1,"two":2}
}
  • 在声明的时候不需要知道map的长度,它也是动态增长的
  • 未初始化的map的值是nil
  • key可以是任意能使用==或者!=操作符比较的类型(string,int,float),数组和切片、结构体不可以作为key,但是接口和指针类型可以(后面会学),如果需要用结构体来作为key,可以使用Key()Hash()方法通过计算结构体的域来计算出唯一的数字或者字符串的key(后面会学)
  • value可以是任意类型的,可以使用空接口类(后面会学),可以存储任意值,但是使用这种类型作为值时需要先做一次类型断言(后面会学)

map 传递给函数的代价很小:在 32 位机器上占 4 个字节,64 位机器上占 8 个字节,无论实际上存储了
多少数据。通过 key 在 map 中寻找值是很快的,比线性查找快得多,但是仍然比从数组和切片的索引中
直接读取要慢 100 倍;所以如果你很在乎性能的话还是建议用切片来解决问题

⭐️ map可以用函数作为value,这里就可以用来做分支结构,直接调用value对应的key来调用此函数

func main() {
	map1 := map[string]func() int{
		"one": func() int {
			return 1
		},
		"two": func() int {
			return 2
		},
		"three": func() int {
			return 3
		},
	}
	fmt.Println(map1) //输出的是地址
}

map[one:0xe33c60 three:0xe33ca0 two:0xe33c80]


//或者是
func main() {
	map1 := map[string]func(i int) int{
		"one": func(i int) int {
			return i
		},
		"two": func(i int) int {
			return i
		},
		"three": func(i int) int {
			return i
		},
	}
	fmt.Println(map1["one"](4)) //输出4
}

⭐️ 调用value的方法和数组类似,直接就是map名[key名]就好了,

func main() {
	map1 := map[string]int{"one": 1, "two": 2} //声明一个map,基础方法 其中string为key的类型,int为value的类型
	map1["three"] = 3                          //将map1的可以three的值改为3,如果没有这个key则添加
	
	test := map1["two"] //将指定key的赋予给test,如果key类型不存在则会被赋值为map1类型的空值
	fmt.Print(map1["one"], map1["two"], map1["three"], test)
}

//输出
1 2 3 2

⭐️ 如果想要删除键值对,直接使用delete即可

	map1 := map[string]int{"one": 1, "four": 4, "five": 5, "three": 3, "two": 2}
	delete(map1, "four")
🌟 map容量

⭐️ map可以根据新增的key-value来动态的伸缩,因此它不存在固定长度或者最大限制,但是在初始化的时候可以选择表面map的初始容量

func main() {
	map1 := make(map[string]int,100) //在切片中使用make是一样的
}

map 增长到容量上限的时候,如果再增加新的key-value对,map 的大小会自动加 1。所以出于性能
的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明

🌟 用切片作为map的值

⭐️ 既然一个 key 只能对应一个 value,而 value 又是一个原始类型,那么如果一个 key 要对应多个值怎么
办?例如,当我们要处理unix机器上的所有进程,以父进程(pid 为整形)作为 key,所有的子进程(以
所有子进程的 pid 组成的切片)作为 value。通过将 value 定义为 []int 类型或者其他类型的切片,就可
以优雅的解决这个问题

func main() {
	map1 := make(map[int][]int)
}

2️⃣ 测试键值对是否存在及删除元素

⭐️ 在获取一个键值对时,就算哪个键不存在,也会返回一个value所属类型的空值,不好判断这个key是否存在,可以使用下面这种方法来判断是否存在

test 返回一个 bool 值:如果 two 存在于 map1two 就是 two 对应的 value 值,并且
testtrue;如果 two 不存在,va 就是一个空值,并且 test 会返回 false

func main() {
	var va int
	var test bool
	map1 := make(map[string]int)
	map1["one"] = 1
	int, test = map1["tow"] 
	println(test, va)
}

3️⃣ For-range

⭐️ 和数组切片一样,但是map 不是按照 key 的顺序排列的,也不是按照 value 的序排列的

func main() {
	map1 := make(map[string]int)
	map1["one"] = 1
	map1["two"] = 2
	map1["three"] = 3
	for key, value := range map1 {
		println("Key: ", key, "Value: ", value)
	}
}

//第一次输出
Key:  one Value:  1
Key:  two Value:  2
Key:  three Value:  3
//第二次输出
Key:  three Value:  3
Key:  one Value:  1
Key:  two Value:  2

4️⃣ map类型的切片

⭐️ 想获取一个 map 类型的切片,我们必须使用两次 make() 函数,第一次分配切片,第二次分配
切片中每个 map 元素

func main() {
	map1 := make([]map[string]int, 5) //分配切片
	for i := range map1 {
		map1[i] = make(map[string]int, 1) //分配切片中的每个map元素
		map1[i]["a"] = i
	}
	fmt.Print(map1)
}

⚠️ 错误方法

func main() {
	map1 := make([]map[string]int, 5)
	for _, test := range map1 {
		test = make(map[string]int, 1) //这里只是获取map的一个拷贝,并不是修改map
		test["a"] = 2
	}
	fmt.Print(map1) 
}
//输出
[map[] map[] map[] map[] map[]]

5️⃣ map的排序

⭐️ map是无序的,如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序(使用 sort 包,然后可以使用切片的 for-range 方法打印出所有的 keyvalue

func main() {
	map1 := map[string]int{"one": 1, "four": 4, "five": 5, "three": 3, "two": 2}
	delete(map1, "four")
	test := make([]string, len(map1)) //创建一个切片,长度为map1的长度
	var i int                         //i为切片的索引
	for key, _ := range map1 {        //读取map的key值,存入对应索引的test切片
		test[i] = key
		i++
	}
	sort.Strings(test)         //使用sort排序切片
	for _, key := range test { //去读按照切片内的值
		fmt.Printf("Key:%v,Value: %v ", key, map1[key])
	}
}

//输出:
Key:five,Value: 5 Key:one,Value: 1 Key:three,Value: 3 Key:two,Value: 2

6️⃣将map的健和值对调

⭐️ 很难直接对map使用键和值对调,因为可能是键和值的类型不一样,

func main() {
	map1 := map[string]int{"one": 1, "four": 4, "five": 5, "three": 3, "two": 2} //初始map
	map2 := make(map[int]string, len(map1)) //键值对调后的map
	for k, v := range map1 {
		map2[v] = k
	}
	fmt.Println(map2)
}

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

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

相关文章

Maven详解—(详解Maven,包括Maven依赖管理以及声明周期,Maven仓库、idea集成Maven)

文章目录 Maven详解一.初始Maven1.1 概述1.2 作用 二.Maven模型2.1 概述2.2 构建生命周期/阶段2.3 项目对象模型2.4 依赖管理模型 三.Maven仓库四.Maven安装4.1 下载4.2 安装步骤 五.Idea集成Maven Maven详解 一.初始Maven 1.1 概述 Maven是Apache旗下的一个开源项目&#x…

虚拟滚动 - 从基本实现到 Angular CDK

简介 在大数据列表的处理上,虚拟滚动是一种优化性能的有效方式。本篇文章将详细介绍两种常见的虚拟滚动实现方式:使用 transform 属性和 Intersection Observer。重点讲解如何通过 transform 属性实现高效的虚拟滚动,并对比Angular CDK中的实…

Spring Boot 配置文件启动加载顺序

前言 Spring Boot的启动加载顺序是一个涉及多个步骤和组件的过程。Spring Boot通过一系列默认设置简化了应用程序的配置,使得开发者能够快速地搭建和部署应用。为了实现这一目标,Spring Boot采用了一种分层和优先级机制来加载配置文件。 一、Spring Bo…

C# Modbus RTU通讯回顾

涉及技术: 1.使用NMdbus4 库 2.ushort[]转int 记得之前刚学习的时候,是ushort[] → Hex字符串→byte[] → 翻转byte[] →BitConverter.ToInt32(),饶了一大圈;实际上可以直接转;这里也有小细节:使用BitCo…

HFSS学习笔记(五)金属过孔、复制模型带激励等问题(持续更新...)

HFSS学习笔记(五)金属过孔、复制模型带激励等问题(持续更新…) 一、金属过孔设计 方法一:用介质减去金属圆柱体,然后再添加金属圆柱体 方法二:嵌入金属圆柱 圆柱过孔选择材料为“copper” HFS…

Late Chunking×Milvus:如何提高RAG准确率

01. 背景 在RAG应用开发中,第一步就是对于文档进行chunking(分块),高效的文档分块,可以有效的提高后续的召回内容的准确性。而对于如何高效的分块是个讨论的热点,有诸如固定大小分块,随机大小分…

大屏可视化:舞动数据与美观的“设计秘籍”

大屏可视化鉴赏:踏入软件系统产品设计之旅,让我们一同鉴赏那些闪耀在智慧农业、智慧园区、智慧社区及智慧港口等领域的大屏可视化杰作。每一帧画面,都是科技与创新的完美融合,数据跃然屏上,智慧触手可及。 >> 数…

基于STM32的智能声音跟随小车设计

引言 本项目基于STM32微控制器设计了一个智能声音跟随小车,通过集成麦克风阵列实现声音源定位和跟随功能。该系统可以检测环境中的声音信号,如手掌拍击声或语音指令,驱动小车向声源方向移动。项目涉及硬件设计、声音信号处理算法以及电机控制…

Bruno解决SSL验证问题

在测试接口的时候,我使用的是Bruno这个软件,开源离线的API测试软件。 主页是这样子的 今天在测试一个HTTPS的接口时候,因为这个HTTPS接口是用的是自签证书,所以就报错误了。 Error invoking remote method send-http-request: …

【论文速读】| APOLLO:一种基于 GPT 的用于检测钓鱼邮件并生成警告用户的解释的工具

基本信息 原文标题:APOLLO: A GPT-based tool to detect phishing emails and generate explanations that warn users 原文作者:Giuseppe Desolda, Francesco Greco, Luca Vigan 作者单位:University of Bari “A. Moro”, Italy, King’…

jfrog artifactory oss社区版,不支持php composer私库

一、docker安装 安装环境:centos操作系统,root用户。 如果是mac或ubuntu等操作系统的话,会有许多安装的坑等着你。 一切都是徒劳,安装折腾那么久,最后还是不能使用。这就是写本文的初衷,切勿入坑就对了。 …

WindowsDocker安装到D盘,C盘太占用空间了。

Windows安装 Docker Desktop的时候,默认位置是安装在C盘,使用Docker下载的镜像文件也是保存在C盘,如果对Docker使用评率比较高的小伙伴,可能C盘空间,会被耗尽,有没有一种办法可以将Docker安装到其它磁盘,同时Docker的数据文件也保存在其他磁盘呢? 答案是有的,我们可以…

vue常见题型(1-10)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 2.2双向绑定的原理是什么vue框架采用的是数据双向绑定的方式,由三个重要部分构成2.2.1.ViewModel2.2.2 双向绑定2.2.3.1.编译Compile2.2.3.2.依赖收集 3…

python怎么将字符串转换为数字

python如何将列表中的字符串转为数字?具体方法如下: 有一个数字字符的列表: numbers [1, 5, 10, 8] 想要把每个元素转换为数字: numbers [1, 5, 10, 8] 用一个循环来解决: new_numbers []; for n in numbers:new_n…

大数据新视界 -- 大数据大厂之 Impala 性能优化:解锁大数据分析的速度密码(上)(1/30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Flutter 插件 sliding_up_panel 实现从底部滑出的面板

前言 sliding_up_panel 是一个 Flutter 插件,用于实现从底部滑出的面板。它在设计上非常灵活,能够适应多种 UI 场景,比如从底部滑出的菜单、可拖动的弹出面板等。以下是 sliding_up_panel 的详细用法,包括常用的参数说明和示例代…

大客户营销数字销售实战讲师培训讲师唐兴通专家人工智能大模型销售客户开发AI大数据挑战式销售顾问式销售专业销售向高层销售业绩增长创新

唐兴通 销售增长策略专家、数字销售实战导师 专注帮助企业构建面向AI数字时代新销售体系,擅长运用数字化工具重塑销售流程,提升销售业绩。作为《挑战式销售》译者,将全球顶尖销售理论大师马修狄克逊等理论导入中国销售业界。 核心专长&…

es数据同步(仅供自己参考)

数据同步的问题分析: 当MySQL进行增删改查的时候,数据库的数据有所改变,这个时候需要修改es中的索引库的值,这个时候就涉及到了数据同步的问题 解决方法: 1、同步方法: 当服务对MySQL进行增删改的时候&…

入门车载以太网(3) -- 网络层

目录 1. 网络通信示例 2. IP地址类别 3. IP数据报 4. 小结 今天继续车载以太网,聊聊网络层。 1. 网络通信示例 我们首先回顾车载以太网的数据传输模型。 从7层开始(车载以太网模糊了5-7层,统称应用层),每个中间层都为上层提供功能&…

六个核桃斥资千万研究脑健康,核桃健脑作用科学具象化了

健康,是这两年热度居高不下的社会话题。对健康的追求影响了诸多领域的发展,上至尖端科研,下至日常接触的食品饮料,都已被卷入大势。 其中,“脑健康”这个听起来更前沿的话题,又已经成为格外重要的一个领域…