映射 
在编程语言中大都会存在一种映射(key-value)类型,在 Python 中叫字典类型,而在 Go 中则叫 map 类型。
map 的底层实现是 hash table,根据 key 查找 value 的时间复杂度是 O(1)。
声明 
map 为关键字,string 表示 key 的数据类型为字符串,int 表示 value 的数据类型为整数。
go
func main() {
	var m map[string]int  // map[key]value
	fmt.Println(m)        // map[]
	fmt.Println(m == nil) // true
	fmt.Printf("%#v", m)  // map[string]int(nil)
}1
2
3
4
5
6
2
3
4
5
6
如果 map 没有被显式初始化,其值是 nil(空 map)。
初始化 
方式一:
go
func main() {
	info := map[string]string{"name": "张三", "age": "18"} // 声明并初始化
	fmt.Println(info) // map[age:18 name:张三]
}1
2
3
4
2
3
4
方式二,可通过内置 make 函数来初始化 map:
go
func main() {
	info := make(map[string]string) // 声明并初始化
    // info := map[string]string{} // 跟上面是等价的
	info["name"] = "张三"
	info["age"] = "23"
	fmt.Println(info) // map[age:23 name:张三]
}1
2
3
4
5
6
7
2
3
4
5
6
7
如果可能的话,最好对 map 使用规模做出粗略估算,并使用 cap 参数对 map 进行初始化:m := make(map[int]string, 10)。
添加和删除 
go
func main() {
	info := make(map[string]string)
	info["name"] = "张三" // 往map中添加键值对
	info["name"] = "李四" // 会覆盖之前的值
	info["sex"] = "男"
	info["age"] = "23"
	delete(info, "age")          // 从map中删除键值对
	fmt.Println(info, len(info)) // map[name:李四 sex:男] 2
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
map 值也可以是一个函数:
go
func main() {
  m := map[int]func(x int) int{}
  m[0] = func(x int) int { return x }
  m[1] = func(x int) int { return x * x }
  m[2] = func(x int) int { return x * x * x }
  fmt.Println(m[0](3), m[1](3), m[2](3)) // 3 9 27
}1
2
3
4
5
6
7
2
3
4
5
6
7
元素查找 
即根据 key 找 value,在访问的 key 不存在时,仍会返回零值。
go
func main() {
	info := map[string]string{"name": "张三", "age": "18"}
	fmt.Println(info["name"])       // 张三
	fmt.Printf("%q\n", info["sex"]) // "" 返回零值
}1
2
3
4
5
2
3
4
5
返回零值可能存在两种情况:
- key 对应元素不存在
- key 对应的元素存在,其值就是零值
go
func main() {
	info := map[string]string{"name": "张三", "age": "18"}
	if value, ok := info["sex"]; ok {
		fmt.Println(value)
	} else {
		fmt.Println("键不存在!")
	}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
遍历 
go
func main() {
	info := map[string]string{"name": "张三", "age": "18"}
	for k, v := range info {
		fmt.Println(k, v)
	}
	// 仅遍历key
	for k := range info {
		fmt.Println(k)
	}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
排序 
map 默认是无序的,Go 中也没有提供专门针对 map 的 key 进行排序的方法。map 排序,可先将 key 进行排序,然后根据 key 值遍历输出即可。
go
func main() {
	info := map[int]string{1: "张三", 2: "18", 0: "男"}
	var keys []int
	for k, _ := range info {
		keys = append(keys, k)
	}
	sort.Ints(keys)
	for _, k := range keys {
		fmt.Println(k, info[k])
	}
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
map 类型切片 
切片中的元素为 map 类型时的操作:
go
func main() {
	var mapSlice = make([]map[string]string, 3)
	// 对切片中的map元素进行初始化
	mapSlice[0] = make(map[string]string, 10)
	mapSlice[0]["name"] = "张三"
	mapSlice[0]["age"] = "18"
	mapSlice[0]["sex"] = "男"
	for i, v := range mapSlice {
		fmt.Printf("index: %d  value: %v\n", i, v)
	}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
切片类型 map 
map 中值为切片类型时的操作:
go
func main() {
	var sliceMap = make(map[string][]string, 3)
	key := "中国"
	value, ok := sliceMap[key]
	if !ok {
		value = make([]string, 0, 2)
	}
	value = append(value, "北京", "上海")
	sliceMap[key] = value
	fmt.Println(sliceMap)
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
