《Go语音圣经(中文版)》笔记(10)
Contents
#《Go 语音圣经(中文版)》
#复合数据类型
#Map
哈希表是一个无序的key/value
对的集合,其中所有的key
都是不同的,然后通过给定的key
可以在常数时间复杂度内检索、更新或删除对应的value
。
在Go
语言中,一个map
就是一个哈希表的引用,map
类型可以写为map[K]V
,其中K
和V
分别对应key
和value
,map
中所有的key
都有相同的类型,所有的value
也有着相同的类型,但是key
和value
之间可以是不同的数据类型。其中K
对应的key
必须是支持==
比较运算符的数据类型,所以map
可以通过测试key
是否相等来判断是否已经存在。
内置的make
函数可以创建一个map
:
1 | ages := make(map[string]int) |
也可以用map
字面值的语法创建map
,同时还可以指定一些最初的key/value
:
1 | ages := map[string]int{ |
1 | // ------------------------------------------- |
map[string]int{}
可以用来创建空的map
的表达式。
使用内置的delete
函数可以删除元素:
1 | delete(ages, "alice") |
如果一个查找失败将返回value
类型对应的零值。
x += y
和x++
等简短赋值语法也可以用在map
上。
map
中的元素并不是一个变量,因此我们不能对map
的元素进行取址操作,原因是map
可能随着元素数量的增长而重新分配更大的内存空间,从而可能导致之前的地址无效。
map
的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。
map
类型的零值是nil
,也就是没有引用任何哈希表。
1 | var ages map[string]int |
map
上的大部分操作,包括查找、删除、len
和range
循环都可以安全工作在nil
值的map
上,它们的行为和一个空的map
类似。但是向一个nil
值的map
存入元素将导致一个panic
异常:
1 | ages["carol"] = 21 // panic: assignment to entry in nil map |
在向map
存数据前必须先创建map
。
通过key
作为索引下标来访问map
将产生一个value
。如果key
在map
中是存在的,那么将得到与key
对应的value
;如果key
不存在,那么将得到value
对应类型的零值。
第二个返回值用来确定对应的元素是否真的是在map
之中:
1 | age, ok := ages["bob"] |
在这种场景下,map
的下标语法将产生两个值,第二个是一个布尔值,用于报告元素是否真的存在。布尔变量一般命名为ok
,特别适合马上用于if
条件判断部分。
map
之间不能进行相等比较,唯一的例外是和nil
进行比较。
有时候我们需要一个map
或set
的key
是slice
类型,但是map
的key
必须是可比较的类型,但是slice
并不满足这个条件。不过,我们可以通过两个步骤绕过这个限制。第一步,定义一个辅助函数k
,将slice
转为map
对应的string
类型的key
,确保只有x
和y
相等时k(x) == k(y)
才成立。然后创建一个key
为string
类型的map
,在每次对map
操作时先用k
辅助函数将slice
转化为string
类型。
map
的value
类型也可以是一个聚合类型,比如是一个map
或slice
。
1 | // ------------------------------------------- |
1 | [11:05:51] onns@Onns ~/Documents/code/go/go-bible/ch4 $ go run 4.4.go |