go入门练习005:map
map基本知识点
创建map:
ages := make(map[string]int) // mapping from strings to ints
ages := map[string]int{
"alice": 31,
"charlie": 34,
}
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34
map基操:
ages["alice"] = 32//访问
delete(ages, "alice") // remove element ages["alice"]
ages["bob"]++ //支持++,即使bob不存在也不会报错
//遍历
for name, age := range ages {
fmt.Printf("%s\t%d\n", name, age)
}
// age可以省略,即key遍历
for name := range ages {
fmt.Printf("%s\n", name)
}
map的零值也是nil,但大多数map的操作对nil都是安全的,添加元素除外:
var ages map[string]int
fmt.Println(ages == nil) // "true"
fmt.Println(len(ages) == 0) // "true"
ages["carol"] = 21 // panic: assignment to entry in nil map
既然访问不存在的key不会报错,而是返回零值,那如何区分key不存在,还是它的值就是零值呢?
if age, ok := ages["bob"]; !ok {
/* key不存在,您看着办... */
}
实现集合功能
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)
}
}
如何存储key不支持==的类型
如果要存储key为slice等不支持==
的类型,需要定义一个辅助函数,将该类型转换为支持==的类型,如string。
如果要存储slice的key,思路如下:
var m = make(map[string]int)//实际还是存string的key
func k(list []string) string { return fmt.Sprintf("%q", list) }//辅助函数将slice转化为string
func Add(list []string) { m[k(list)]++ }
func Count(list []string) int { return m[k(list)] }
map的value支持任何类型
map的value没有限制,可以灵活使用。下面的例子用map实现了有向图的存储:
//gragh为有向图,key为string,表示当前节点;
//value为map[string]bool,表示后继节点,
//所以gragh[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]
}