golang第十三天,Map

222 阅读4分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

什么是Map

  1. map是golang中的内置类型,它将一个值与一个值关联起来。可以使用相应的键检索值
  2. map是一种无序的键值对的集合。map最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值
  3. map是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,map是无序的,我们无法决定它的返回顺序,这是因为map是使用hash表来实现的,也是引用类型

map无序是有原因的:主要是通过散列函数对key计算一个唯一值与值进行映射,通过散列函数对我们的map

注意:

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

使用make()创建map

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

// 声明变量 默认map是nil
var mapValue map[keyType]valueType

// 使用make函数
mapValue = make(map[keyType]valueType)
rating := map[string]float32 {"c": 5, "go":4.5,"python":4, "c++": 2}

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

package main
import "fmt"
func main() {
    var countryCapitalMap map[string]string
    // 创建集合
    countryCapitalMap = make(map[string]string)
    
    // map插入key-value对,每个国家对应自己的首都
    countryCapitalMap["France"] = "Paris"
    countryCapitalMap["Italy"] = "Rome"
    countryCapitalMap["Japan"] = "Tokyo"
    countryCapitalMap["India"] = "New Delhi"
    
    /* 使用 key 输出 map 值 */
    for country := range countryCapitalMap {
       fmt.Println("Capital of",country,"is",countryCapitalMap[country])
    }
    /* 查看元素在集合中是否存在 */
    captial, ok := countryCapitalMap["United States"]
    /* 如果 ok 是 true, 则存在,否则不存在 */
    if(ok){
       fmt.Println("Capital of United States is", captial)  
    }else {
       fmt.Println("Capital of United States is not present") 
    }
}

运行结果:

image.png

map的长度

使用len函数可以确定map的长度

len(map). // 可以得到map的长度

map的删除

delete()函数

delete(map, key) 函数用于删除集合的元素, 参数为 map 和其对应的 key。删除函数不返回任何值。

package main

import "fmt"

func main() {   
   /* 创建 map */
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"}

   fmt.Println("原始 map")   

   /* 打印 map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }

   /* 删除元素 */
   delete(countryCapitalMap,"France");
   fmt.Println("Entry for France is deleted")  

   fmt.Println("删除元素后 map")   

   /* 打印 map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
}

运行结果:

image.png

ok-idiom

我们可以通过key获取map中对应的value值。语法为:

map[key] 

但是当key如果不存在的时候,我们会得到该value值类型的默认值,比如string类型得到空字符串,int类型得到0。但是程序不会报错。

所以我们可以使用ok-idiom获取值,可知道key/value是否存在

value, ok := map[key] 

示例代码:

package main

import (
    "fmt"
)

func main() {
    m := make(map[string]int)
    m["a"] = 1
    x, ok := m["b"]
    fmt.Println(x, ok)
    x, ok = m["a"]
    fmt.Println(x, ok)
}

运行结果:

image.png

  1. 在申明同时赋值
// 更常用的方法是使用map字面量。map的初始长度会根据初始化时指定的键值对的数量来确定。
var mapVariables3 = map[string]int{
    "Monday": 1, "Tuesday": 2, "Wednesday": 3,
    "Thursday": 4, "Friday": 5, "Saturday": 6, "sunday": 7,
}
  1. 短冒号,简短声明
mapVariables2 := make(map[string]string)
mapVariables2["Monday"] = "周一"
mapVariables2["Tuesday"] = "周二"
mapVariables2["Wednesday"] = "周三"
  1. map 切片, map+切片
//interface{} 可以把它当作万能类型
var mapVariables6 []map[string]interface{}
mapVariables6 = make([]map[string]interface{},2)
mapVariables6[0] = make(map[string]interface{},2)
mapVariables6[0]["name"] = "小阿肥"
mapVariables6[0]["age"] = 18

mapVariables6[1] = make(map[string]interface{},2)
mapVariables6[1]["name"] = "大阿肥"
mapVariables6[1]["age"] = 16

map是引用类型

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

示例代码:

package main

import (  
    "fmt"
)

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)

}

运行结果:

image.png

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

刚学golang,希望大家监督并且一起努力

有兴趣的小伙伴,欢迎关注我订阅号:EntrepreneurialG