3.3.2 基本操作
下面通过make函数来创建一个map:
m1 := make(map[string]int)
通过上面的方式创建了一个k类型为string、v类型为int的map。
用户也可以直接使用map关键字创建带有初始值的map,示例如下:
m2 := map[string]int{ "k1":11, "k2":22 }
如果要访问11这个值,就要使用m2[“k1”]的方式。如果要删除该元素,则可以使用delete函数,写法如下:
delete(m2,"k1")
与之相关的一些具体操作可通过如下代码来了解。
book/ch03/3.3/main.go
1. package main
2.
3. import "fmt"
4.
5. func main() {
6. m1 := make(map[string]int)
7. m1["k1"]=11
8. m1["k2"]=22
9. print(m1)
10. delete(m1,"k1")
11. print(m1)
12. delete(m1,"k1")
13. print(m1)
14.
15. val,ok := m1["k1"]
16. if ok {
17. fmt.Println(val)
18. }else{
19. fmt.Println("not exist")
20. }
21.
22. var m2 map[string]int
23. m2["kk1"] = -11
24. }
25.
26. func print(m map[string]int) {
27. for k,v := range m{
28. fmt.Println(k,v)
29. }
30. }
31.
32. //以下是程序执行结果
33. k1 11
34. k2 22
35. k2 22
36. k2 22
37. not exist
38. panic: assignment to entry in nil map
第6行至第9行,先通过make函数定义了一个映射(map),然后给该map增加了k1:11、k2:22两个键值对。第9行,调用了print函数,注意第26行至第29行print函数的写法,里面用range关键字对map进行了遍历。输出结果在第33行和第34行。
第10行至第13行,先用delete函数把k1的键值对删除,从第11行的输出结果(见第35行)可以看到k1确实被删除。第12行再删除k1,此时应该已经没有k1了,但是不会报错,从第36行的输出结果可知,这里确实只有k2。也就是说删除一个map中没有的键时并不报错。接下来看如何判断map里面是否有某键。
注意第15行,取m[“k1”]值的时候,返回的是两个数据,一个是value值,一个是“是否存在”。比如本例,k1已经不存在了,ok就为false,这时执行第19行,执行结果见第37行。
第22行和第23行,定义了一个map m2,但是没有带初始值,这时候执行第23行就会报错。
注意
map在元素赋值之前必须初始化,要么使用make函数,要么声明的时候就带着初始值,这样比较安全,可以避免使用时报错。
在上例中,delete函数执行时,没有元素也不会报错,我们访问某元素,比如m[“KKK”],虽然map中没有该键,但是并不会报错,而是会返回值类型的默认初始值,本例int的默认初始值就是0。
注意
map类型的默认初始值是nil,也就是说未初始化的map是nil。尽管如此,未初始化的map执行删除元素、len操作、range操作或查找元素时都不会报错。但是如果在初始化之前进行元素赋值则会报错。
map的遍历顺序是不固定的,不同的机器可能对Hash算法的使用会有所不同,而且从实际应用来看,map的遍历顺序确实体现出无序的特征。如果要对map排序,需要对key进行排序,然后根据安装key的顺序取值来达到map排序的效果。
与slice相比,map除了本身的key-value结构以外,对底层内存的使用也更为高效。map的value可以是struct等复合数据结构,所以使用也是比较灵活的。