go语言map

一、基本介绍

map是key-value数据结构,是一种无序的键值对的集合。

二、基本语法

var 变量名 map[keytype]valuetype

keytype可以是很多类型,比如bool,数字,string,指针,channel,还可以是包含前面几个类型的接口,结构体,数组,通常为int、string。
注意:slice,map还有function不可以作为key,因为这几个没法用==来判断

valuetype的类型和keytype基本一样,通常为数字,string,map,struct

var a map[string]string
var b map[int]string
var c map[int]int
var d map[string]int
var e map[string]map[string]string

注意:声明是不会分配内存的,初始化需要make分配内存后才能赋值和使用

三、map使用方式

  1. 先声明后赋值
package main

import (
	"fmt"
)

func main() {
	var myMap map[string]string
	myMap = make(map[string]string, 2)
	myMap["name"] = "小明"
	myMap["age"] = "18"
	fmt.Printf("myMap=%v\n", myMap)
}
  1. 声明时直接make
package main

import (
	"fmt"
)

func main() {
	myMap := make(map[string]string, 2)
	myMap["name"] = "小明"
	myMap["age"] = "18"
	fmt.Printf("myMap=%v\n", myMap)
}
  1. 声明时直接赋值

import (
	"fmt"
)

func main() {
	myMap := map[string]string{
		"name": "小明",
		"age":  "18",
	}
	fmt.Printf("myMap=%v\n", myMap)
}

四、map的增删改查

  1. map[key] = value //如果key还没有就是增加,如果key存在就是修改。
  2. 删除,使用内置函数delete()
func delete(m map[Type]Type1, key Type)

如果key存在,就会删除该key-value,如果key不存在,不操作,但是也不会增加。

package main

import (
	"fmt"
)

func main() {
	myMap := map[string]string{
		"name": "小明",
		"age":  "18",
	}
	delete(myMap, "name")
	fmt.Printf("myMap=%v\n", myMap)
}

细节说明:

  • 如果我们要删除map的所有key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除
  • 或者map = make(...),make一个新的map,让原来的称为垃圾,被gc回收
  1. map查找
package main

import (
	"fmt"
)

func main() {
	myMap := map[string]string{
		"name": "小明",
		"age":  "18",
	}
	value, ok := myMap["name"]
	if ok {
		fmt.Printf("myMap=%v\n", value)
	} else {
		fmt.Println("没找到")
	}
}

说明:如果myMap这个map中存在"name",那么ok就会为true,否则为false

五、map的遍历

使用for-range来遍历

package main

import (
	"fmt"
)

func main() {
	myMap := map[string]string{
		"name": "小明",
		"age":  "18",
	}
	for key, value := range myMap {
		fmt.Printf("key=%v,value=%v\n", key, value)
	}
}

输出结果:

key=name,value=小明
key=age,value=18

六、map切片

切片的类型如果是map,则我们称为slice of map,map切片,这样使用则map个数就可以动态变化了。

package main

import (
	"fmt"
)

func main() {
	mapSlice := make([]map[string]string, 2)
	mapSlice[0] = map[string]string{
		"name": "小明",
		"age":  "18",
	}
	mapSlice[1] = map[string]string{
		"name": "小红",
		"age":  "19",
	}
	newMap := map[string]string{
		"name": "小王",
		"age":  "20",
	}
	// 动态添加map
	mapSlice = append(mapSlice, newMap)
	fmt.Printf("mapSlice=%v\n", mapSlice)
}

输出结果:

mapSlice=[map[age:18 name:小明] map[age:19 name:小红] map[age:20 name:小王]]

七、map排序

  1. golang中没有专门的方法针对map的key进行排序
  2. golang中的map默认是无需的,也不是按照添加的顺序存放的,每次遍历,得到的输出可能不一样。
  3. golang中的排序,是先对key进行排序,然后根据key遍历输出即可
package main

import (
	"fmt"
	"sort"
)

func main() {
	var intMap map[int]int = make(map[int]int, 10)
	intMap[0] = 12
	intMap[8] = 15
	intMap[9] = 10
	intMap[7] = 23
	intMap[5] = 12
	intMap[6] = 50
	intMap[3] = 78
	intMap[1] = 10
	intMap[2] = 82
	intMap[4] = 30
	// 无序的
	fmt.Println("排序前················")
	for key, value := range intMap {
		fmt.Printf("key=%v,value=%v\n", key, value)
	}
	fmt.Println("排序前················")
	// 1.先将map的key放到切片中
	// 2.对切片进行排序
	// 3.遍历切片,然后按照key来输出map的值
	keySlice := make([]int, 10)
	for key, _ := range intMap {
		keySlice = append(keySlice, key)
	}
	sort.Ints(keySlice)
	fmt.Println("排序后················")
	for _, key := range keySlice {
		fmt.Printf("key=%v,value=%v\n", key, intMap[key])
	}
	fmt.Println("排序后················")
}

输出结果:

排序前················
key=0,value=12
key=7,value=23
key=5,value=12
key=6,value=50
key=1,value=10
key=8,value=15
key=9,value=10
key=3,value=78
key=2,value=82
key=4,value=30
排序前················
排序后················
key=0,value=12
key=1,value=10
key=2,value=82
key=3,value=78
key=4,value=30
key=5,value=12
key=6,value=50
key=7,value=23
key=8,value=15
key=9,value=10
排序后················

八、注意细节

  1. map是一个引用类型,遵守引用类型传递机制。一个函数接收map,修改后,会直接修改原来的map
package main

import (
	"fmt"
)

func ModifyMap(intMap map[int]int, key int) {
	intMap[key] = 888
}

func main() {
	var intMap map[int]int = make(map[int]int, 5)
	intMap[0] = 12
	intMap[8] = 15
	intMap[9] = 10
	intMap[7] = 23
	intMap[5] = 12
	fmt.Println("修改前···························")
	for key, value := range intMap {
		fmt.Printf("key=%v,value=%v\n", key, value)
	}
	fmt.Println("修改前···························")

	ModifyMap(intMap, 5)

	fmt.Println("修改后···························")
	for key, value := range intMap {
		fmt.Printf("key=%v,value=%v\n", key, value)
	}
	fmt.Println("修改后···························")
}

输出结果:

修改前···························
key=0,value=12
key=8,value=15
key=9,value=10
key=7,value=23
key=5,value=12
修改前···························
修改后···························
key=9,value=10
key=7,value=23
key=5,value=888
key=0,value=12
key=8,value=15
修改后···························
  1. map的容量达到后,再向map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
  2. map的value也经常使用struct类型,更适合管理复杂的数据
posted @ 2021-05-19 23:08  若雨蚂蚱  阅读(107)  评论(0编辑  收藏  举报