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]
}

posted on 2020-10-23 10:18  caffebabe  阅读(114)  评论(0编辑  收藏  举报