go语言中map每次遍历的顺序不同-问题分析
WHAT?
发现下面这段代码,多次运行出的结果是不一样的
mapper := make(map[int]string)
mapper[1] = "1"
mapper[2] = "2"
mapper[3] = "3"
mapper[4] = "4"
mapper[5] = "5"
mapper[6] = "6"
mapper[7] = "7" for k, v := range mapper {
fmt.Println(k, v)
}
HOW?
从下面图片中看到,range获取迭代器是通过调用了mapiterinit()方法。(图片来源:https://my.oschina.net/renhc/blog/2396058)

然后看到mapiterinit方法里,有取随机数的部分。java语言每次都会按顺序去遍历桶,而go语言会提前取一个随机数,把桶的遍历顺序随机化。
(图片来源:https://blog.csdn.net/u010853261/article/details/99699350)
(也可以直接看map源码。mapiterinit在https://github.com/golang/go/blob/36f30ba289e31df033d100b2adb4eaf557f05a34/src/runtime/map.go 第797行。下图的这段代码在827行)

WHY?
遍历map的时候,每次取随机数,看起来是没有意义的,为什么要这样设计呢?(寻找答案的时候,看到有些博客说go的早期版本的map遍历没有取随机数这个步骤)
(图片来源:https://blog.csdn.net/slvher/article/details/44779081)

读完上面的内容,我的理解就是:如果没有设置这个随机数,那么在大多数情况下,golang会表现出map的顺序是固定的情况。但是golang底层并没有保证这一点,或许(现在/以后)会有特殊情况出现顺序不固定的情况。担心开发者们误解这一点,golang就特意去打乱了这个顺序,让开发者们知道golang底层不保证map每次遍历都是同一个顺序。
go语言中map每次遍历的顺序不同-问题分析的更多相关文章
- 项目中一次排序规则的改动,注意到js中map的遍历的顺序
背景:项目需要对前端页面上某个插件的下拉选择项进行排序,需要按照配置的顺序显示. 首先调查后台,发现sql语句中已经添加order by.之后发现查询结果遍历后封装进HashMap,这里改为LinkH ...
- 011_go语言中的range遍历
代码演示 package main import "fmt" func main() { nums := []int{2, 3, 4} sum := 0 for _, num := ...
- 关于C语言中for循环的执行顺序
for(初始值赋值操作A:终止条件B:递增操作C) { 循环体D: } 其执行次序为:A->B->D->C->B->D->C->B--.. 直到B条 ...
- C-C++到底支不支持VLA以及两种语言中const的区别
C-C++到底支不支持VLA以及两种语言中const的区别 到底支不支持VLA VLA就是variable-length array,也就是变长数组. 最近写程序的时候无意间发现,gcc中竟然支持下面 ...
- 【翻译】go语言中的map实战
业余时间翻译,水平很差,如有瑕疵,纯属无能. 原文链接 http://blog.golang.org/go-maps-in-action go语言中的map实战 1. 简介 哈希表是计算机科学中最重要 ...
- Go语言中的map(十一)
map是一种无序的基于 key-value 的数据结构,Go语言中的map是引用类型,所以跟切片一样需要初始化才能使用. 定义map 定义 map 的语法如下: map[keyType]ValueTy ...
- 浅谈Java语言中try{}catch{}和finally{}的执行顺序问题
浅谈Java语言中try{}catch{}和finally{}的执行顺序问题 2019-04-06 PM 13:41:46 1. 不管有没有出现异常,finally块中代码都会执行: 2. 当t ...
- 掌握R语言中的apply函数族(转)
转自:http://blog.fens.me/r-apply/ 前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是 ...
- R语言中apply函数
前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是为什么呢?原因在于R的循环操作for和while,都是基于R语言 ...
随机推荐
- 《HTTPS权威指南》读书笔记——PKI
互联网公钥基础设施 基于可信的第三方机构(CA,certification authority)实现不同成员在不见面的情况下进行安全通信 订阅人 需要证书来提供安全服务的团体 登记机构(RA) 完成证 ...
- 【cf932E】E. Team Work(第二类斯特林数)
传送门 题意: 求\(\displaystyle \sum_{i=0}^n{n\choose i}i^k,n\leq 10^9,k\leq 5000\). 思路: 将\(i^k\)用第二类斯特林数展开 ...
- 工具推荐--刷LeetCode的神器
本文首发于微信公众号:[坂本先生],文章地址为: https://mp.weixin.qq.com/s/vHv5hO8nils_g2VSKwu1Cg如有转载请标明出处 今天给大家安利一款快速刷Leet ...
- 菜鸟刷面试题(一、Java基础篇)
目录: JDK 和 JRE 有什么区别? == 和 equals 的区别是什么? 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? final 在 java 中有什 ...
- 手机投屏工具与HOSTS切换工具
ApowerMirror windows -->switchhosts
- Educational Codeforces Round 77 (Rated for Div. 2)
A: 尽可能平均然后剩下的平摊 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int ...
- C#函数的递归
using System; namespace ConsoleApp3 { class Program { static void Main(string[] args) { ); Console.W ...
- 操作系统篇之Linux命令操作和redis安装以及基本使用
电脑操作系统 : windows7,8,10,xp,win98 操作系统 : linux ax unix 以后开发项目是部署在服务器上,服务器一般采用linux. linux的优点:系统稳定,操作速度 ...
- JS基础语法---创建对象---三种方式创建对象:调用系统的构造函数;自定义构造函数;字面量的方式
创建对象三种方式: 调用系统的构造函数创建对象 自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象) 字面量的方式创建对象 第一种:调用系统的构造函数创建对象 //小苏举例子: //实例化对 ...
- 图像几何变换之平移(Matlab)
G=imread('aini555.jpg'); A=rgb2gray(G); se=translate(strel(),[,]); B=imdilate(A,se); figure; subplot ...