Go maps

Go maps 类似于其他编程语言的哈希表,在 Python 中称为字典,Ruby 为散列,而 JavaScript 则被称为对象,PHP 是关联数组。

不像数组和切片,maps 的主要优点是它们可以使用任何数据类型作为索引,在这种情况下称为映射键或 key。

尽管 Go maps 不排除任何数据类型作为键,但要用作的数据类型必须具有 可比性,这意味着 Go 编译器必须能够区分一个键和另一个键,或者简单地说 ,映射的键必须支持 == 运算符。

创建 maps

你可以创建一个空 map,并用 string 作为键,int 作为值,在 go 中可以用 ​​make()​​ 函数创建:

myMap = make(map[string] int)

或者指定一个 预先分配的空间,就像分配切片的容量一样:

myMap := make(map[int]string, 18)

这里的 ​​string​​​ 就是键类型, ​​int​​ 就是值的类型,我们也可以按如下方式创建:

myMap := make(map[string]int)
myMap["小王"] = 17
myMap["小李"] = 19
myMap["老王"] = 51

也可以通过 ​​map​​ 关键字来创建一个 map:

myClass := map[string]int {
"小王": 17,
"小李": 19,
"老张": 51,
}

maps 取值

然后我们可以通过 ​​myClass["小王"]​​​ 和 ​​myClass["老张"]​​ 来取值,将会分别得到 17 和 51 的结果。

如果程序中访问的键并不存在于 myClass 中,那么 Go 将会根据值的类型返回相应的零值作为结果,比如 ​​myClass["张三"]​​ 就会返回结果为“0”。

Tips: 正因为,当我们想尝试获取maps中不存在的键的值,最终会得到零,导致我们无法确定结果实际上是0,还是因为没有这个值导致的值为0。所以在Go语言中有 ​​_, ok​​ 的用法。

这个 ok 也不是必须这样命名,可以设置为其他非关键字 命名法,比如 age, found := myClass["张三"]

删除 maps

可以通过 ​​delete()​​ 函数来删除一个 map 的元素,比如删除班级中的小李:

delete(myClass, "小李")

maps 迭代

for key, value := range myClass {
fmt.Println(key, value)
}

代码演示

创建一个 myMaps.go 文件,

package main

import (
"fmt"
)

func main() {

myMap := make(map[string]int)
myMap["小王"] = 17
myMap["小李"] = 19
myMap["老王"] = 51
fmt.Println("myMap:", myMap)

myClass := map[string]int{
"小王": 17,
"小李": 19,
"老张": 51,
}

fmt.Println("myClass:", myClass)

delete(myClass, "小李")
fmt.Println("myClass:", myClass)
for key, value := range myClass {
fmt.Println(key, value)
}

fmt.Println("myClass[\"张三\"]:", myClass["张三"])
_, ok := myClass["张三"]
if ok {
fmt.Println("张三存在~")
} else {
fmt.Println("张三不存在!")
}
}

当我们执行上述代码时,将会得到如下结果:

myMap: map[小李:19 小王:17 老王:51]
myClass: map[小李:19 小王:17 老张:51]
myClass: map[小王:17 老张:51]
小王 17
老张 51
myClass["张三"]: 0
张三不存在!

总结

maps 比切片和数组更通用,但这种灵活性是有代价的:实现 Go maps 所需的额外的空间。 但是,内置的 Go 在算法上实现的这种结构非常快,所以在需要时不要犹豫使用 Go maps。 Go maps 非常方便,可以存储多种不同类型的数据,尤其当我们需要追求查询速度的时候,就该想到maps,同时易于理解且易于使用。