环球头条:Go 语言 map 如何顺序读取?
原文链接:Go 语言 map 如何顺序读取?
Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。
然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。
(资料图)
现象
先看一段代码示例:
package mainimport "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 mainimport ( "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
关键词:
相关阅读
-
环球头条:Go 语言 map 如何顺序读取?
**原文链接:**[Go语言map如何顺序读取?](https: mp weixin q... -
配售申购是什么(配售申购是什么意思)
来为大家解答以上问题。配售申购是什么,配售申购是什么意思这个很... -
国家文物局、文化和旅游部等部门联合印...
国家文物局、文化和旅游部等部门联合印发《三峡文物保护利用专项规划》 -
全球微头条丨日立电梯故障代码(日立电梯...
10主微机故障11副微机故障12运行接触器短接故障14安全继电器短接故... -
梅州市教育局:2023广东梅州中考成绩查...
1 查询渠道2023年广东梅州中考成绩查询通常需要到学校或者教育局进... -
全球速读:5月26日基金净值:华夏创成长...
5月26日,华夏创成长ETF最新单位净值为0 5355元,累计净值为1 948...
精彩放送
-
环球头条:Go 语言 map 如何顺序读取?
**原文链接:**[Go语言map如何顺序读取?](https: mp weixin q... -
配售申购是什么(配售申购是什么意思)
来为大家解答以上问题。配售申购是什么,配售申购是什么意思这个很... -
国家文物局、文化和旅游部等部门联合印...
国家文物局、文化和旅游部等部门联合印发《三峡文物保护利用专项规划》 -
全球微头条丨日立电梯故障代码(日立电梯...
10主微机故障11副微机故障12运行接触器短接故障14安全继电器短接故... -
梅州市教育局:2023广东梅州中考成绩查...
1 查询渠道2023年广东梅州中考成绩查询通常需要到学校或者教育局进... -
全球速读:5月26日基金净值:华夏创成长...
5月26日,华夏创成长ETF最新单位净值为0 5355元,累计净值为1 948... -
电流继电器符号表示(电流继电器符号)
1、电流继电器的符号继电器新符号用字母K表示,以前用J表示。2、细... -
强对流天气来袭 武汉一夜打雷1000多次...
人民网武汉5月26日电(记者张沛)25日傍晚开始,一场“雷暴”惊扰了... -
2023内蒙古西部计划考试时间+地点+科目...
2023年内蒙古自治区大学生志愿服务西部计划招募考试2023年内蒙古自... -
当前播报:饮湖上初晴后雨古诗文网_饮湖...
1、古诗原文其一朝曦迎客艳重冈,晚雨留人入醉乡。2、此意自佳君不...