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 mainimport "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 mainimport "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 mainimport "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 mainimport ("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])}}
