GO语言学习笔记(与Java的比较学习)(五)

Map

概念

map 是引用类型,可以使用如下声明:

var map1 map[keytype]valuetype
var map1 map[string]int
  • 在声明的时候不需要知道 map 的长度,map 是可以动态增长的。

  • 未初始化的 map 的值是 nil(即零值为nil),nil 映射既没有键,也不能添加键。

key 可以是任意可以用 == 或者!= 操作符比较的类型,比如 string、int、float。所以切片和结构体不能作为 key ,但是指针和接口类型可以。(含有数组切片的结构体不能作为 key,只包含内建类型的 struct 是可以作为 key 的)如果要用结构体作为 key 可以提供 Key()Hash() 方法,这样可以通过结构体的域计算出唯一的数字或者字符串的 key。

value 可以是任意类型的;通过使用空接口类型,我们可以存储任意值,但是使用这种类型作为值时需要先做一次类型断言

如果 key1 是 map1 的 key,那么 map1[key1] 就是对应 key1 的值,就如同数组索引符号一样(数组可以视为一种简单形式的 map,key 是从 0 开始的整数)。

常用的 len(map1) 方法可以获得 map 中的 pair 数目,这个数目是可以伸缩的,因为 map-pairs 在运行时可以动态添加和删除。

map 是 引用类型 的: 内存用 make 方法来分配。

map 的初始化:

var map1 = make(map[keytype]valuetype)

或者简写为:

map1 := make(map[keytype]valuetype)

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

map 容量

和数组不同,map 可以根据新增的 key-value 对动态的伸缩,因此它不存在固定长度或者最大限制。但是你也可以选择标明 map 的初始容量 capacity,就像这样:

make(map[keytype]valuetype, cap)

例如:

map2 := make(map[string]float32, 100)

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

用切片作为 map 的值

mp1 := make(map[int][]int)
mp2 := make(map[int]*[]int)

用结构体作为 map 的值

package main
​
import "fmt"
​
type Vertex struct {Lat, Long float64
}
​
var m = map[string]Vertex{"Bell Labs": Vertex{40.68433, -74.39967,},"Google": Vertex{37.42202, -122.08408,},
}
​
func main() {fmt.Println(m)
}

测试map中是否存在查询键所对应的值

测试 map1 中是否存在 key1:

val1, isPresent = map1[key1]

isPresent 返回一个 bool 值:如果 key1 存在于 map1,val1 就是 key1 对应的 value 值,并且 isPresent 为 true;如果 key1 不存在,val1 就是一个空值,并且 isPresent 会返回 false。

如果你只是想判断某个 key 是否存在而不关心它对应的值到底是多少,你可以这么做:

_, ok := map1[key1] // 如果key1存在则ok == true,否则ok为false

或者和 if 混合使用:

if _, ok := map1[key1]; ok {// ...
}
package main
​
import "fmt"
​
func main() {var value stringvar isPresent bool// 创建一个mapmap1 := make(map[int]string)map1[0] = "a"map1[1] = "b"map1[2] = "c"map1[3] = "d"map1[4] = "e"value, isPresent = map1[3]if isPresent {fmt.Printf("the value of %d is %s", 3, value)}
}

从 map1 中删除 key1:

直接 delete(map1, key1) 就可以。

package main
​
import "fmt"
​
func main() {var value stringvar isPresent bool// 创建一个mapmap1 := make(map[int]string)map1[0] = "a"map1[1] = "b"map1[2] = "c"map1[3] = "d"map1[4] = "e"value, isPresent = map1[3]if isPresent {fmt.Printf("the value of %d is %s\n", 3, value)}delete(map1, 3)value, isPresent = map1[3]// 删除完成后需要检查是否存在,如若没有这行代码,后续依旧会输出“the value of 3 is d”,这是由于“if isPresent {”这段代码弟弟isPresent检查的是是否成功删除,因为成功删除了3,所以会打印if代码段内容if isPresent {fmt.Printf("the value of %d is %s", 3, value)} else {fmt.Println("no such value")}
}

for-range 的配套用法

可以使用 for 循环构造 map:

for key, value := range map1 {...
}

第一个返回值 key 是 map 中的 key 值,第二个返回值则是该 key 对应的 value 值;这两个都是仅 for 循环内部可见的局部变量。其中第一个返回值 key 值是一个可选元素。如果你只关心值,可以这么使用:

for _, value := range map1 {...
}

如果只想获取 key,你可以这么使用:

for key := range map1 {fmt.Printf("key is: %d\n", key)
}

示例:

package main
​
import "fmt"
​
func main() {// 创建一个mapmap1 := make(map[int]string)map1[0] = "a"map1[1] = "b"map1[2] = "c"map1[3] = "d"map1[4] = "e"// 输出所有 key 和 valueprintln("打印所有key,value")for key, value := range map1 {fmt.Printf("The key is %d, the value is %s\n", key, value)}print("____________________________________________________")println("只打印value")for _, value := range map1 {fmt.Printf("The value is %s\n", value)}print("____________________________________________________")println("只打印key")for key := range map1 {fmt.Printf("The key is %d\n", key)}
}

map 的排序

map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序,如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序。

将 map 的键值对调

这里对调是指调换 key 和 value。如果 map 的值类型可以作为 key 且所有的 value 是唯一的,那么通过下面的方法可以简单的做到键值对调。

package main
import ("fmt"
)
​
var (barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,"delta": 87, "echo": 56, "foxtrot": 12,"golf": 34, "hotel": 16, "indio": 87,"juliet": 65, "kili": 43, "lima": 98}
)
​
func main() {invMap := make(map[int]string, len(barVal))for k, v := range barVal {invMap[v] = k}fmt.Println("inverted:")for k, v := range invMap {fmt.Printf("Key: %v, Value: %v / ", k, v)}
}

学习参考资料:

《Go 入门指南》 | Go 技术论坛 (learnku.com)

Go 语言之旅

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

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

相关文章

国际化 Vue-i18n的安装与使用 (Vue2.0 / Vue3.0)

国际化 Vue-i18n的安装与使用 (Vue2.0 / Vue3.0) 一、Vue-i18n是什么? Vue-I18n是 Vue.js 的国际化插件。它可以轻松地将一些本地化功能集成到你的 Vue.js 应用程序中。简单来说就是可以帮助用户进行语言的切换” 二、使用步骤 1.引入库 代码…

智慧城市的创新实践:全球案例分享

一、引言 在全球化和数字化的时代,智慧城市已经成为城市发展的前沿趋势。智慧城市运用先进的信息技术,如大数据、物联网、云计算和人工智能等,提升城市管理的智能化水平,增强公共服务效率,优化居民生活质量。本文将通…

第四十九回 吴学究双掌连环计 宋公明三打祝家庄-Python与HTTP服务交互

吴用请戴宗从梁山请来铁面孔目裴宣、圣手书生萧让、通臂猿侯健、玉臂匠金大坚来帮忙。又告诫扈家庄的扈成,打起来不要去帮祝家庄。 孙立把旗号改成“登州兵马提辖孙立”,来祝家庄找峦廷玉,被热情接待。 第三天,宋江派小李广花荣…

HTML代码简单介绍

目录 HTML结构介绍 HTML文件基本结构 标签的层次结构 HTML结构介绍 HTML的代码由标签构成 例如&#xff1a; <head>Hello</head> 标签名 body 放到 < > 中大部分标签成对出现 <body> 为开始标签, </body> 为结束标签.少数标签只有开始标签…

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍

1.简介 学习音视频开发&#xff0c;首先从做一款播放器开始是比较合理的&#xff0c;每一章节&#xff0c;我都会将源码贴在最后&#xff0c;此专栏你将学习到以下内容&#xff1a; 1&#xff09;音视频的解封装、解码&#xff1b; 2&#xff09;Qtopengl如何渲染视频&#…

Docker实战——容器

目录 Docker 容器的基本概念与操作1.使用“docker create”创建容器。这里基于Nginx的镜像创建了一个容器&#xff0c;名字为mycontainer。2.使用“docker ps -a”命令查看所有的容器&#xff0c;这时的容器不一定是运行状态。3.使用 “docker start” 命令可以启动容器。4.使用…

优化zabbix对Docker API的监控

启用Zabbix Agent 2对Docker API的监控&#xff0c;通常不需要直接编辑/etc/zabbix/zabbix_agent2.d/下的文件&#xff0c;因为针对Docker容器的监控是通过内建的插件实现的。以下是大致步骤&#xff1a; 确认Agent版本与配置&#xff1a; 确保你安装的是支持Docker监控的Zabbi…

安卓内存信息查看

目录 前言一、Android查看内存相关信息的方法1.1 通过 adb shell 获取内存信息1.2 通过编程方式获取内存信息1.3 adb shell 获取应用程序内存使用情况1.4 free指令 二、总结 前言 一、Android查看内存相关信息的方法 1.1 通过 adb shell 获取内存信息 C:\Users\henry.xue>…

JMeter正则表达式提取器和JSON提取器基础用法,小白必会!

【面试突击班】1. 性能测试主要关注哪些指标&#xff1f; 最近在利用JMeter做接口自动化测试&#xff0c;正则表达式提取器和JSON提取器用的还挺多&#xff0c;想着分享下&#xff0c;希望对大家的接口自动化测试项目有所启发。 在 JMeter 中&#xff0c;正则表达式和 JSON 提…

代码随想录算法训练营第二十六天 | 39. 组合总和 40.组合总和II 131.分割回文串

39. 组合总和 https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:result []self.backtracking(candidates, target,0, [], result,0)return…

探索Ubuntu命令行:常见问题与解决方案

一、引言 Ubuntu&#xff0c;作为一款流行的Linux发行版&#xff0c;其命令行界面&#xff08;CLI&#xff09;为用户提供了丰富的功能和灵活性。然而&#xff0c;对于新手来说&#xff0c;命令行可能会带来一些挑战。本文将探讨一些在使用Ubuntu命令行时可能遇到的问题及其解决…

C语言内存优化实用指南

一、引言 在C语言编程中&#xff0c;内存管理是一项至关重要的任务。有效的内存优化可以提升程序的性能&#xff0c;减少资源消耗&#xff0c;并防止可能出现的内存泄漏和溢出问题。以下是一些关于C语言内存优化的实用指南。 二、理解内存管理 在C语言中&#xff0c;程序员需…

VMware虚拟机安装Linux

1.新建虚拟机 2. 安装操作系统 等待 选择中文 点软件选择 选择下面的GNOME桌面 禁用KDUMP 点进安装位置&#xff0c;点完成就可以了 网络连接&#xff0c;右上角打开 开始安装&#xff0c;输入ROOT密码&#xff0c;创建用户 点击重启&#xff0c;等待 重启完成之后出现下面的界…

分巧克力.

题目描述 儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。 小明一共有块巧克力&#xff0c;其中第块是Hw的方格组成的长方形。为了公平起见 小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足: 1.形状是正方形&#xff0c;边…

Windows10蓝牙开关按钮不见了问题??

Windows10蓝牙开关按钮不见了问题&#xff1f;&#xff1f;此类问题一般是系统更新不及时的bug&#xff0c;遗漏掉了蓝牙相关驱动插件 试过很多方法&#xff0c;直接下载一个驱动人生即可&#xff0c;主要通过官网下载 下载这个就行 打开软件自动扫描就可以了 最后查看结果

python二级常见题目

一.常见语法 jieba—第三方中文分词函数库 jieba—第三方中文分词函数库_jieba库函数-CSDN博客 Python基础——format格式化 Python基础——format格式化_python format-CSDN博客 format()方法的使用超全_format方法-CSDN博客 Python中random函数用法整理 Python中random…

C#面:什么是虚方法?它与接口有什么不同?

虚方法&#xff1a; 虚方法是在基类中声明的方法&#xff0c;可以在派生类中进行重写。通过使用关键字"virtual"来标记虚方法。派生类可以根据需要重新实现该方法。 虚方法和接口的主要区别在于&#xff1a; 虚方法是在基类中定义的&#xff0c;派生类可以选择性地…

web安全学习笔记【19】——信息打点(9)

信息打点-红蓝队自动化项目&资产侦察&武器库部署&企查产权&网络空间[1] #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-CM…

【Web】关于FastJson反序列化开始前的那些前置知识

目录 FastJson介绍 FJ序列化与反序列化方法 关于反序列化三种方式的关系与区别 FastJson反序列化漏洞原理通识 关于getter&setter FastJson介绍 FastJson&#xff08;快速JSON&#xff09;是一个Java语言编写的高性能、功能丰富且易于使用的JSON解析和序列化库。它由…

python梅花易数,python算卦

2024-02-28 python梅花易数&#xff0c;python算卦&#xff0c;梅花易数的三数起卦 前言&#xff1a;本来想搜来直接复制的&#xff0c;结果看目前找到的都有些问题&#xff0c;特意去看了梅花易数的视频&#xff0c;写了个。想法被拿捏的死死的&#xff0c;不如相信算卦 # …