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使用方式
- 先声明后赋值
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)
}
- 声明时直接make
package main
import (
"fmt"
)
func main() {
myMap := make(map[string]string, 2)
myMap["name"] = "小明"
myMap["age"] = "18"
fmt.Printf("myMap=%v\n", myMap)
}
- 声明时直接赋值
import (
"fmt"
)
func main() {
myMap := map[string]string{
"name": "小明",
"age": "18",
}
fmt.Printf("myMap=%v\n", myMap)
}
四、map的增删改查
- map[key] = value //如果key还没有就是增加,如果key存在就是修改。
- 删除,使用内置函数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回收
- 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排序
- golang中没有专门的方法针对map的key进行排序
- golang中的map默认是无需的,也不是按照添加的顺序存放的,每次遍历,得到的输出可能不一样。
- 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
排序后················
八、注意细节
- 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
修改后···························
- map的容量达到后,再向map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
- map的value也经常使用struct类型,更适合管理复杂的数据