为什么Go的地图迭代顺序在打印时会有所变化?

huangapple go评论107阅读模式
英文:

Why does Go's map iteration order vary when printing?

问题

上面的Go代码只是打印了一个map[string]string三次。

我期望它输出是固定的,但实际上显示如下:

map[key3:value3 key2:value2 key1:value1]
map[key1:value1 key3:value3 key2:value2]
map[key2:value2 key1:value1 key3:value3]

它是变化的!

而在Python中:

#!/bin/env python
#encoding=utf8

sample = {
    "key1":"value1",
    "key2":"value2",
    "key3":"value3",
}
for i in range(3):
    print sample

输出:

{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
英文:
package main

import "fmt"

func main(){
    sample := map[string]string{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3",
    }
    for i := 0;i<3;i++{
        fmt.Println(sample)
    }
}

The above go code just print a map[string]string three times.

I expect it to a fixed output,but it shows as the following:

map[key3:value3 key2:value2 key1:value1]
map[key1:value1 key3:value3 key2:value2]
map[key2:value2 key1:value1 key3:value3]

It varies!

while in python:

#!/bin/env python
#encoding=utf8

sample = {
    "key1":"value1",
    "key2":"value2",
    "key3":"value3",
}
for i in range(3):
    print sample

OutPut:

{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}`

答案1

得分: 15

你不能依赖于获取键的顺序。语言规范中说:“映射是一个无序的元素组”,并且后面还说:“映射的迭代顺序没有指定,并且不能保证从一次迭代到下一次迭代是相同的。”

英文:

You cannot rely on the order in which you will get the keys. The language spec says "A map is an unordered group of elements", and later "The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next."

答案2

得分: 6

是的,它是变化的,甚至是有意的(在修改前的地图迭代之前是稳定的)。目的是尽早捕捉到某人错误地假设稳定迭代保证的情况。此外,随着地图实现的自由度增加,运行时库的这部分可能会有更多可能的未来优化。

英文:

Yes, it varies and even intentionally (iteration of a non modified map has been stable before). The intent is to catch as early as possible the situation when someone wrongly assumes a stable iteration guarantee. Additionally, with the added freedom for map implementation there comes more possible future optimizations of that part of the run time library.

答案3

得分: 3

Python不能保证迭代的顺序,但是只要在调用之间不修改字典,它保证顺序将保持稳定:

如果在没有对字典进行任何修改的情况下调用items()、keys()、values()、iteritems()、iterkeys()和itervalues(),列表将直接对应。

Go也不能保证。从你的例子来看,Go的顺序可能是稳定的,只是起始点不同,但是由于没有任何保证,不要依赖它。

英文:

Python does not guarantee the order of iteration, but it does guarantee that the order will remain stable so long as you do not modify the dictionary between calls:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are
called with no intervening modifications to the dictionary, the lists will 
directly correspond.

Go does not guarantee either. It looks from your example as though the order in Go may be stable and only the starting point varies, but as nothing is guaranteed don't depend on it.

答案4

得分: 0

我理解你不应该依赖于map的迭代顺序,因为它没有逻辑顺序。

除此之外,我相信Go语言对于map的迭代实现是有意随机的(http://nathanleclaire.com/blog/2014/04/27/a-surprising-feature-of-golang-that-colored-me-impressed/ 和 http://www.confreaks.com/videos/3419-gophercon2014-opening-day-keynote),这是为了阻止人们在他们的代码中依赖它。

希望对你有所帮助。

英文:

As I understand that you should not depend on the order of the iterator for the map, since it has no logical ordering.

That aside, I believe that Go's implementation for map iteration is intentionally random (http://nathanleclaire.com/blog/2014/04/27/a-surprising-feature-of-golang-that-colored-me-impressed/ and http://www.confreaks.com/videos/3419-gophercon2014-opening-day-keynote) that is to discourage people from relying on it in their code.

I hope that helps.

huangapple
  • 本文由 发表于 2012年12月6日 21:50:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/13744996.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定