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,同时易于理解且易于使用。