8.1 介绍
map也是引用类型。
声明:var map1 map[int]string
map在声明的时候不需要声明长度,因为它是可以动态增长的。
未初始化的map的值是nil。
和其他语言的字典的作用类似,以键值对key:value作为元素。
key可以是string,int,float,指针,接口等类型,数组切片结构体等不行,value可以任意类型。
map不存在固定长度,或最大容量,但定义的时候是可以指定初始容量的。
map1 := make(map[int]string, 500)
8.2 map的操作
要获取一个key的值,可以使用val1 := map1[key1],获取key1对应的值,如果这个key1不存在,则返回空值。但是如果这个key1的值就是空值呢?
可以使用isPresent解决上述困扰。
package main
import "fmt"
func main() {
map1 := map[int]string{1: "a", 2: "b", 3: "c"}
val1 := map1[4]
fmt.Println(val1) //字符串空值""
val2, isPresent := map1[4]
if isPresent == false {
fmt.Println("key不存在")
} else {
fmt.Println(val2)
}
}
由此可以拓展到,如果你这是想判断某个key存不存在,那么可以:
if _,ok := map[key]; ok{
...
}
使用for range结构来循环遍历map。
package main
import "fmt"
func main() {
map1 := map[int]string{1: "a", 2: "b", 3: "c"}
for key, value := range map1 {
fmt.Println(key, value)
}
}
// 2 b
// 3 c
// 1 a
可以看到,输出并不是按照123这样的顺序输出的,说明map是无序的。
map的本质其实是散列表,map的增容回导致重新进行散列,导致map的遍历结果在扩容前后不可靠。
8.3 map类型的切片
想要得到一个map类型的切片需要两次make,第一次分配切片,第二次才分配切片的元素。
package main
import "fmt"
func main() {
sli := make([]map[int]int, 5) //初始化map类型的切片
for i := range sli {
sli[i] = make(map[int]int, 10) //初始化切片的元素
sli[i][1] = 1 //给元素赋值
}
fmt.Println(sli) //得到5个元素[map[1:1] map[1:1] map[1:1] map[1:1] map[1:1]]
}
8.4 map的排序
map是无序的,无论是key还是value都是无序的。
如果想要排序map,需要到切片,把key或value拷贝到一个切片,在切片里用sort()排序好,因为key和value是对应的,那么按照排序号的切片key来输出value,就实现了map的排序输出。
package main
import (
"fmt"
"sort"
)
func main() {
map1 := map[int]int{
1: 1,
3: 3,
2: 2,
}
sli1 := []int{}
for k := range map1 {
sli1 = append(sli1, k) //把key存到切片中
}
sort.Ints(sli1) //切片升序
for _, i := range sli1 {
fmt.Println(i, map1[i])
}
}