《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
标记已存在的行。
go
复制代码
func main() {
seen := make(map[string]bool) // a set of strings
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]依然可以返回一个有意义的结果。
go
复制代码
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]
}