Golang通脉之map

Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。

map 是一种无序的键值对的集合。map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值 map 是一种集合,所以可以像迭代数组和切片那样迭代它。不过,map 是无序的,无法决定它的返回顺序,这是因为 map 是使用 hash 表来实现的,Go语言中的map是引用类型,必须初始化才能使用。

使用map过程中需要注意的几点:

  • map是无序的,每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取
  • map的长度是不固定的,也就是和slice一样,也是一种引用类型
  • 内置的len函数同样适用于map,返回map拥有的key的数量
  • map的key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型……也可以键。

定义

Go语言中 map的定义语法如下:

map[KeyType]ValueType

其中,

  • KeyType:表示键的类型。
  • ValueType:表示键对应的值的类型。

**map类型的变量默认初始值为nil,需要使用make()函数来分配内存 (声明并初始化) **。语法为:

make(map[KeyType]ValueType,[cap])

其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。

可以使用内建函数 make ,也可以使用 map 关键字来定义 Map:

/* 声明变量,默认 map 是 nil */
var mapVariable map[KeyType]ValueType

/* 使用 make 函数 */
mapVariable = make(map[keyType]ValueType)
rating := map[string]float32 {"C":5,"Go":4.5,"Python":4.5,"C++":2 }

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

基本使用

map中的数据都是成对出现的:

func main() {
 scoreMap := make(map[string]int,8)
 scoreMap["张三"] = 90
 scoreMap["小明"] = 100
 fmt.Println(scoreMap)
 fmt.Println(scoreMap["小明"])
 fmt.Printf("type of a:%T\n",scoreMap)
}

输出:

map[小明:100 张三:90]
100
type of a:map[string]int

map也支持在声明的时候填充元素,例如:

func main() {
 userInfo := map[string]string{
  "username": "张三","password": "123456",}
 fmt.Println(userInfo) //
}

判断键是否存在

Go语言中有个判断map中键是否存在的特殊写法,格式如下:

value,ok := map[key]
func main() {
 /* 创建集合 */
   countryCapitalMap := make(map[string]string)
   
   /* map 插入 key-value 对,各个国家对应的首都 */
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
 // 如果key存在ok为true,v为对应的值;不存在ok为false,v为值类型的零值
 v,ok := countryCapitalMap["United States"]
 if ok {
  fmt.Println("Capital of United States is",captial)  
   }else {
      fmt.Println("Capital of United States is not present") 
   }
}

map的遍历

Go语言中使用for range遍历map。

func main() {
 countryCapitalMap := make(map[string]string)
   /* map 插入 key-value 对,各个国家对应的首都 */
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
 for k,v := range countryCapitalMap {
  fmt.Println(k,v)
 }
}

只想遍历key的时候,可以按下面的写法:

func main() {
 countryCapitalMap := make(map[string]string)
   /* map 插入 key-value 对,各个国家对应的首都 */
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
 for k := range countryCapitalMap {
  fmt.Println(k)
 }
}

注意: 遍历map时的元素顺序与添加键值对的顺序无关。

delete()函数删除map元素

使用delete()内建函数从map中删除一组键值对,删除函数不返回任何值,delete()函数的格式如下:

delete(map,key)

其中,

  • map:表示要删除键值对的map
  • key:表示要删除的键值对的键
func main(){
 countryCapitalMap := make(map[string]string)
   /* map 插入 key-value 对,各个国家对应的首都 */
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
 delete(countryCapitalMap,"France")//将"France":"Paris"从map中删除
 for k,v := range scoreMap{
  fmt.Println(k,v)
 }
}

指定顺序遍历map

func main() {
 rand.Seed(time.Now().UnixNano()) //初始化随机数种子

 var scoreMap = make(map[string]int,200)

 for i := 0; i < 100; i++ {
  key := fmt.Sprintf("stu%02d",i) //生成stu开头的字符串
  value := rand.Intn(100)          //生成0~99的随机整数
  scoreMap[key] = value
 }
 //取出map中的所有key存入切片keys
 var keys = make([]string,200)
 for key := range scoreMap {
  keys = append(keys,key)
 }
 //对切片进行排序
 sort.Strings(keys)
 //按照排序后的key遍历map
 for _,key := range keys {
  fmt.Println(key,scoreMap[key])
 }
}

map类型的切片

下面的代码切片中的元素为map类型时的操作:

func main() {
 var mapSlice = make([]map[string]string,3)
 for index,value := range mapSlice {
  fmt.Printf("index:%d value:%v\n",index,value)
 }
 fmt.Println("after init")
 // 对切片中的map元素进行初始化
 mapSlice[0] = make(map[string]string,10)
 mapSlice[0]["username"] = "张三"
 mapSlice[0]["password"] = "123456"
 mapSlice[0]["address"] = "深圳"
 for index,value)
 }
}

value为切片类型的map

下面的代码演示了map中值为切片类型的操作:

func main() {
 var sliceMap = make(map[string][]string,3)
 fmt.Println(sliceMap)
 fmt.Println("after init")
 key := "中国"
 value,ok := sliceMap[key]
 if !ok {
  value = make([]string,2)
 }
 value = append(value,"北京","上海")
 sliceMap[key] = value
 fmt.Println(sliceMap)
}

map是引用类型

与切片相似,map是引用类型。当将map分配给一个新变量时,它们都指向相同的内部数据结构。因此,一个的变化会反映另一个:

func main() {  
    personSalary := map[string]int{
        "steve": 12000,"jamie": 15000,}
    personSalary["mike"] = 9000
    fmt.Println("Original person salary",personSalary)
    newPersonSalary := personSalary
    newPersonSalary["mike"] = 18000
    fmt.Println("Person salary changed",personSalary)

}

运行结果:

Original person salary map[steve:12000 jamie:15000 mike:9000]  
Person salary changed map[steve:12000 jamie:15000 mike:18000] 

map不能使用操作符进行比较。只能用来检查map是否为空。否则会报错:invalid operation: map1 == map2 (map can only be comparedto nil)

原文地址:https://www.cnblogs.com/drunkery

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考