https://blog.csdn.net/u011957758/article/details/82846609 前言 前段时间听了大佬们对于map的讲解,结合自己之前的积累,专门来由浅入深的总结一下,希望可以与map之间做一个了断。 文章的深浅顺序是递进的,当你看完这篇文章,你也基本掌握了map的99%的知识点了,可以装逼和吹牛逼了。 正文 1.map的基本使用 1.1声明 & 默认值 // 声明 var m map[string]string 12 map的声明的时候默认值是nil ,此时进行取值,返回的是对应类型的零值(不存在也是返回零值)。 例子: // bool 的零值是false var m map[int]bool a, ok := m[1] fmt.Println(a, ok) // false false // int 的零值是0 var m map[int]int a, ok := m[1] fmt.Println(a, ok) // 0 false 123456789 1.2初始化 // 声明之后必须初始化,才能使用 m = make(map[string]int) m = map[string]int{} // 声明并初始化 <= 注意这里是 := 不是 = m := make(map[string]int) m := map[string]int{1:1} 1234567 向未初始化的map赋值引起 panic: assign to entry in nil map. 1.3key与value的限制 key一定要是可比较的类型(可以理解为支持==的操作): 可比较类型 不可比较类型 boolean slice numeric map string func pointer channel interface 包含前文类型的array和struct 如果是非法的key类型,会报错:invalid map key type xxx。 golang为uint32、uint64、string提供了fast access,使用这些类型作为key可以提高map访问速度。[runtime/hashmap_fast.go] value可以是任意类型。 1.4新增 & 删除 & 更新 & 查询 // 新增 m["name"] = "咖啡色的羊驼" // 删除,key不存在则啥也不干 delete(m, "name") // 更新 m["name"] = "咖啡色的羊驼2" // 查询,key不存在返回value类型的零值 i := m["name"] // 三种查询方式, i, ok := m["name"] _, ok := m["name"] 12345678910111213 1.5遍历 需要强调的是map本身是无序的,在遍历的时候并不会按照你传入的顺序,进行传出。 正常遍历: for k, v := range m { fmt.Println(k, v) } 123 有序遍历: import "sort" var keys []string // 把key单独抽取出来,放在数组中 for k, _ := range m { keys = append(keys, k) } // 进行数组的排序 sort.Strings(keys) // 遍历数组就是有序的了 for _, k := range keys { fmt.Println(k, m[k]) } 123456789101112 1.6函数传参 Golang中是没有引用传递的,均为值传递。这意味着传递的是数据的拷贝。 那么map本身是引用类型,作为形参或返回参数的时候,传递的是值的拷贝,而值是地址,扩容时也不会改变这个地址。 var m map[int64]int64 m = make(map[int64]int64, 1) fmt.Printf("m 原始的地址是:%p\n", m) changeM(m) fmt.Printf("m 改变后地址是:%p\n", m)