golang的map的元素遍历是随机的?为什么这样做?怎么做的?

为什么这样做

大部分的编程语言,对于固定的数据集合,map的元素遍历是顺序,但是golang为什么要搞成随机的呢?

golang的设计哲学是:没有过于灵活地允许马马虎虎的代码,Go强迫你从一开始就把事情弄得直接一点。Go程序员参考里面说如果他们的程序可以编译(而且代码符合Go的风格),那么代码有很大的可能可以像预期的那样工作,这种模模糊糊却不错的感觉也有Go严谨性的贡献。没有诡异的类型bug,丢失分号等等错误。

尤其是,在Andrew的参考文章中,他指出这是Go的设计者们所作出的改变。他们不再允许人们依赖于那些破破烂烂的假设。我最痛恨的一点就是那些破烂的,到处是bug的功能(这发生在交付的产品中,或者是编程语言,等等很多地方),通过权衡,接受,从而变成了一个特性,另外尝试修复这些”特性”真的是很恶心。

怎么实现

如果每输出一个元素都随机的话,一是性能问题,而且还要标记某个元数是否访问到。所以很可能是随机生成一个访问点然后,先将当前桶便历完,然后顺序扫描下一个桶(猜测的,没有看源码,不一定正确),看下面程序的运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
blogArticleViews := map[int]int{
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
10: 10,
}
for key, views := range blogArticleViews {
fmt.Println("There are", views, "views for", key)
}
}

执行结果1:

1
2
3
4
5
6
7
8
9
10
11
There are 1 views for 1
There are 3 views for 3
There are 5 views for 5
There are 7 views for 7
There are 9 views for 9
There are 0 views for 0
There are 2 views for 2
There are 4 views for 4
There are 6 views for 6
There are 8 views for 8
There are 10 views for 10

执行结果2:

1
2
3
4
5
6
7
8
9
10
11
There are 1 views for 1
There are 3 views for 3
There are 5 views for 5
There are 7 views for 7
There are 9 views for 9
There are 0 views for 0
There are 2 views for 2
There are 4 views for 4
There are 6 views for 6
There are 8 views for 8
There are 10 views for 10

执行结果3:

1
2
3
4
5
6
7
8
9
10
11
There are 10 views for 10
There are 0 views for 0
There are 2 views for 2
There are 4 views for 4
There are 6 views for 6
There are 8 views for 8
There are 1 views for 1
There are 3 views for 3
There are 5 views for 5
There are 7 views for 7
There are 9 views for 9

执行结果4:

1
2
3
4
5
6
7
8
9
10
11
There are 1 views for 1
There are 3 views for 3
There are 5 views for 5
There are 7 views for 7
There are 9 views for 9
There are 0 views for 0
There are 2 views for 2
There are 4 views for 4
There are 6 views for 6
There are 8 views for 8
There are 10 views for 10

很可能这个hashTable有两个桶:0,2,4,6,8,10为一个桶, 1,3,5,7,9为一个桶

参考资料

http://golanghome.com/post/155

Comments

2016-04-11