《Go语言圣经》map
禁止取址
禁止取址:map 中的元素不是变量,无法进行取址操作(如 &ages["bob"]
)。因为 map 可能随元素增加重新分配内存,导致地址失效。
nil map
向 nil map 存入元素会触发 panic(如 ages["carol"] = 21
),因此必须先使用 make() 创建 map。
存在性检查
map 的下标语法可返回两个值(如 age, ok := ages["bob"]
),第二个布尔值 ok 用于判断元素是否存在,常用于条件判断。
实现集合(Set)
Go 语言没有内置 Set
类型,但可用 map[string]bool
替代。通过键的唯一性去重,例如 dedup
程序通过 seen[line] = true
标记已存在的行。
func main ( ) { seen := make ( map [ string ] bool ) input := bufio. NewScanner ( os. Stdin) for input. Scan ( ) { line := input. Text ( ) if ! seen[ line] { seen[ line] = true fmt. Println ( line) } } if err := input. Err ( ) ; err != nil { fmt. Fprintf ( os. Stderr, "dedup: %v\n" , err) os. Exit ( 1 ) }
}
嵌套 map
Map的value类型也可以是一个聚合类型,比如是一个map或slice。在下面的代码中,graph 这个 map 的key类型是一个字符串,value类型map[string]bool代表一个字符串集合。从概念上讲,graph将一个字符串类型的key映射到一组相关的字符串集合,它们指向新的graph的key。 其中addEdge函数惰性初始化map是一个惯用方式,也就是说在每个值首次作为key时才初始化。hasEdge函数显示了如何让map的零值也能正常工作;即使from到to的边不存在,graph[from][to]依然可以返回一个有意义的结果。
var graph = make ( map [ string ] map [ string ] bool )
func addEdge ( from, to string ) { edges := graph[ from] if edges == nil { edges = make ( map [ string ] bool ) graph[ from] = edges} edges[ to] = true
}
func hasEdge ( from, to string ) bool { return graph[ from] [ to]
}