共计 1347 个字符,预计需要花费 4 分钟才能阅读完成。
原文链接: Go 语言 map 如何程序读取?
Go 语言中的 map 是一种十分弱小的数据结构,它容许咱们疾速地存储和检索键值对。
然而,当咱们遍历 map 时,会有一个乏味的景象,那就是输入的键值对程序是不确定的。
景象
先看一段代码示例:
package main
import "fmt"
func main() {m := map[string]int{
"apple": 1,
"banana": 2,
"orange": 3,
}
for k, v := range m {fmt.Printf("key=%s, value=%d\n", k, v)
}
}
当咱们多执行几次这段代码时,就会发现,输入的程序是不同的。
起因
首先,Go 语言 map 的底层实现是哈希表,在进行插入时,会对 key 进行 hash 运算。这也就导致了数据不是按顺序存储的,和遍历的程序也就会不统一。
第二,map 在扩容后,会产生 key 的搬迁,原来落在同一个 bucket 中的 key,搬迁后,有些 key 可能就到其余 bucket 了。
而遍历的过程,就是按程序遍历 bucket,同时按程序遍历 bucket 中的 key。
搬迁后,key 的地位产生了重大的变动,有些 key 被搬走了,有些 key 则原地不动。这样,遍历 map 的后果就不可能按原来的程序了。
最初,也是最有意思的一点。
那如果说我曾经初始化好了一个 map,并且不对这个 map 做任何操作,也就是不会产生扩容,那遍历程序是固定的吗?
答:也不是。
Go 杜绝了这种做法,次要是放心程序员会在开发过程中依赖稳固的遍历程序,因为这是不对的。
所以在遍历 map 时,并不是固定地从 0 号 bucket 开始遍历,每次都是从一个随机值序号的 bucket 开始遍历,并且是从这个 bucket 的一个随机序号的 cell 开始遍历。
如何程序读取
如果心愿依照特定程序遍历 map,能够先将键或值存储到切片中,而后对切片进行排序,最初再遍历切片。
革新一下下面的代码,让它按程序输入:
package main
import (
"fmt"
"sort"
)
func main() {m := map[string]int{
"apple": 1,
"banana": 2,
"orange": 3,
}
// 将 map 中的键存储到切片中
keys := make([]string, 0, len(m))
for k := range m {keys = append(keys, k)
}
// 对切片进行排序
sort.Strings(keys)
// 依照排序后的程序遍历 map
for _, k := range keys {fmt.Printf("key=%s, value=%d\n", k, m[k])
}
}
在下面的代码中,首先将 map 中的键存储到一个切片中,而后对切片进行排序。
最初,依照排序后的程序遍历 map。这样就能够依照特定程序输入键值对了。
以上就是本文的全部内容,如果感觉还不错的话欢送 点赞 , 转发 和关注,感激反对。
参考文章:
- https://go.dev/blog/maps
- https://golang.design/go-questions/map/unordered/
举荐浏览:
- Go 语言 map 是并发平安的吗?
- Go 语言切片是如何扩容的?
- Go 语言数组和切片的区别
- Go 语言 new 和 make 关键字的区别
- 为什么 Go 不反对 []T 转换为 []interface
- 为什么 Go 语言 struct 要应用 tags