键值对
//[keytype] 和 valuetype 之间允许有空格。
var mapname map[keytype]valuetype
其中:
- mapname为map的变量名。
- keytype为键类型。
- valuetype是键对应的值类型。
注意
len()
下面请看两个例子:
例子1:
package main
import (
"fmt"
)
func main() {
//初始化一个没有键值对的map
map1 := map[int]int{}
//falsae
fmt.Println(map1 == nil)
//未进行初始化
var map2 map[int]int
//true
fmt.Println(map2 == nil)
}
例子2:
package main
import "fmt"
func main() {
var mapLit map[string]int
var mapAssigned map[string]int
//初始化一个含有两个键值对的map
mapLit = map[string]int{"one": 1, "two": 2}
mapAssigned = mapLit
mapAssigned["two"] = 3
fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])
fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])
fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"])
}
输出结果是什么呢?
输出的结果是
Map literal at "one" is: 1
Map assigned at "two" is: 3
Map literal at "ten" is: 0
因为mapAssigned 是 mapList 的引用,对 mapAssigned 的修改也会影响到 mapList 的值。因此在修改mapAssigned[“two”]为3时,mapList["two]也是3。
map还有另外一种创建方式
make(map[keytype]valuetype,cap)
例如:
map2 := make(map[string]int, 100)
当 map 增长到容量上限的时候,如果再增加新的 key-value,map 的大小会自动加 1,所以出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明。
既然一个 key 只能对应一个 value,而 value 又是一个原始类型,那么如果一个 key 要对应多个值怎么办?
答案是:使用切片
例如,当我们要处理 unix 机器上的所有进程,以父进程(pid 为整形)作为 key,所有的子进程(以所有子进程的 pid 组成的切片)作为 value。
通过将 value 定义为 []int 类型或者其他类型的切片,就可以优雅的解决这个问题,示例代码如下所示:
mp1 := make(map[int][]int)
mp2 := make(map[int]*[]int)