字典是由若干个 key:value 键值对映射组合在一起的数据结构。
字典是基于哈希表的实现,每个映射里的 key 都是唯一且必须是可哈希的,即 key 是不可变类型。
字典的 key 和 value 都有各自的数据类型,在声明字典时必须指定 key 和 value 是什么类型的,然后使用 map 关键字创建字典。
字典的声明初始化字典的声明和初始化一般分为四种方式。
第一种,声明并初始化:
var data map[string]string = map[string]string{
"id": "1",
"name": "极客点儿",
}
第二种,简化声明并初始化:
data := map[string]string{
"id": "1",
"name": "极客点儿",
}
第三种,使用 make() 先声明后赋值:
data := make(map[string]string) data["id"] = "1" data["name"] = "极客点儿"
第四种,先声明,然后使用 make() 申请内存空间,最后赋值:
var data map[string]string data = make(map[string]string) data["id"] = "1" data["name"] = "极客点儿"
先声明 data 是一个 map 类型,此时未初始化的 data 的零值是 nil,无法直接进行赋值,需要使用 make() 申请内存空间,最后再赋值。
正常情况下,不会有人使用第四种这种繁琐的声明方式,最常用的是第二、第三种。
字典的类型字典的声明和数组、切片有一点不同的是字典需要同时给 key 和 value 声明类型。
那么如果我想把不同的类型混合在字典里,比如:字典中的 value 有可能是 int 和 string 类型同时存在。这种情况该如何实现呢?
其实 Go 语言为了提升字典的灵活性,提供了一种任意类型的类型 interface{} :
data := make(map[string]interface {})
data["id"] = 1
data["name"] = "极客点儿"
这样 value 就可以是任意类型了。
当然也可以将 key 也声明为可哈希范围内的任意类型:
data := make(map[interface {}]string)
data[1] = "1"
data["name"] = "极客点儿"
key 和 value 都声明为任意类型:
data := make(map[interface {}]interface {})
data[1] = 1
data["name"] = "极客点儿"
在实际开发中,第一种是最常用的,即 key 声明为字符串,value 声明为任意类型。
字典的操作字典的操作比较简单,最常见的是增删改查操作。
新增:data["user"] = "Golang"修改:
data["name"] = "Golang"
若 key 已存在则直接更新对应的 value。
删除:delete(data, "user")
使用 delete() 删除字典中的元素,当 key 不存在时,delete() 直接忽略不会报错。
查看:通过下标的方式访问:
fmt.Println(data) fmt.Println(data["id"]) fmt.Println(data["name"]) fmt.Println(data["user"])
当 key 不存在时,访问字典并不会报错,而是会返回其 value 数据类型的默认空值。
通过 for-range 进行迭代,迭代还可以分为三种方式。
获取 key 和 value:
for key, value := range data {
fmt.Println(key, value)
}
只获取 key,可以使用占位符 _ 忽略返回值:
for key, _ := range data {
fmt.Println(key)
}
也可以不使用占用符:
for key := range data {
fmt.Println(key)
}
只获取 value,占位符 _ 是必须要的,用来忽略返回值:
for _, value := range data {
fmt.Println(value)
}
判断 key 是否存在
因为字典的特性,当 key 不存在时,访问字典并不会报错,而是会返回其 value 数据类型的默认空值。但是有可能 key 的值恰好就是空值,所以不能直接使用空值来判断 key 是否存在。
其实读取字典的数据是有两个值的,通常我们只需要第一个值,即字典本身的数据。第二个值则是对应的 key 是否存在的布尔值,若存在则为 true 否则就是 false。
_, status := data["name"] fmt.Println(status) // true _, status = data["user"] fmt.Println(status) // false



