ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# **Go 映射(maps)** 一个 Go map(映射,下文不做翻译)就是在其它编程语言中众所周知的哈希表。map数据结构的主要优势就是其可以使用任意数据类型作为键值,但是对于Go map来说并不是所有的数据类型都能作为键值,只有可比较的类型才可以,意思是Go编译器能够区分不同的键值。或者简单来说,Go map的键值必须支持`==`操作符。显而易见,使用`bool`类型作为map的键值是非常不灵活的。另外,由于不同机器和操作系统的浮点数精度定义不同,使用浮点数作为键值可能会出现异常。 >Tip: Go map的底层指向了一个哈希表!Go已经隐藏了哈希表的实现及其复杂性,你将在第五章学习如何使用Go实现一个哈希表。 下面使用`make()`函数以`string`为键类型,以`int`作为值类型创建一个空的map: ```go iMap := make(map[string]int) ``` 同样也可以使用map字面量创建并初始化一个map: ```go anotherMap := map[string]int { "k1": 12, "k2": 13 } ``` 可以使用`anotherMap["k1"]`可以获得对应的值,使用`delete()`删除一个键值对: ```go delete(anotherMap, "k1") ``` 遍历map中得元素可使用如下代码: ```go for key, value := range iMap { fmt.Priintln(key, value) } ``` `usingMaps.go`中的代码将会更加详细地展示map的用法。代码将会分为3部分,第一部分是: ```go package main import ( "fmt" ) func main() { iMap := make(map[string]int) iMap["k1"] = 12 iMap["k2"] = 13 fmt.Println("iMap:", iMap) anotherMap := map[string]int { "k1": 12, "k2": 13, } ``` 第二部分是: ```go fmt.Println("anotherMap:",anotherMap) delete(anotherMap,"k1") delete(anotherMap, "k1") delete(anotherMap, "k1") fmt.Println("anotherMap:",anotherMap) _, ok := iMap["doseItExist"] if ok { fmt.Println("Exist!") } else { fmt.Println("dose NOT exist") } ``` 这里你将学习到如何判断map中拥有某个键值对,这是很重要的知识点,如果不了解的话,你将无法判断一个map是否拥有你想要的信息。 > 需要注意的是,当你尝试使用一个并不存在的键去获取值的时候,返回值是0,但是你并不知道到底是某个键对应的值是0,还是由于所访问的键不存在而返回的0,这是为什么我们使用`_, ok`. 另外,代码中多次调用delete()去删除同一个元素并不会导致异常或者警告。 最后一部分代码展示了使用`range`关键字遍历map是非常简洁和方便的: ```go for key, value := range iMap { fmt.Println(key, value) } } ``` 执行`usingMaps.go`将会得到下面的输出: ```bash $ go run usingMaps.go iMap: map[k1:12 k2:13] anotherMap: map[k1:12 k2:13] anotherMap: map[k2:13] dose NOT exist k1 12 k2 13 ``` >Tip: 你不能也不应该期望键值对是按顺序打印的,因为遍历map时其顺序是随机的。