3
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)
    }
}

上面的 go 代码只打印了 3 次 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'}`
4

4 回答 4

15

您不能依赖获得密钥的顺序。语言规范“映射是一组无序的元素”,后来“映射的迭代顺序没有指定,并且不保证从一次迭代到下一次迭代顺序相同”。

于 2012-12-06T13:53:13.727 回答
6

是的,它是变化的,甚至是有意的(未修改地图的迭代之前一直很稳定)。目的是尽早发现有人错误地假设稳定迭代保证的情况。此外,随着地图实现的自由度增加,未来可能会对该部分运行时库进行优化。

于 2012-12-06T14:12:15.863 回答
3

Python 不保证迭代的顺序,但它确实保证只要您不修改调用之间的字典,顺序就会保持稳定:

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

Go 也不保证。从您的示例中看起来,Go 中的顺序可能是稳定的,只有起点会有所不同,但因为没有任何东西可以保证不依赖它。

于 2012-12-06T14:06:16.310 回答
0

据我了解,您不应该依赖地图迭代器的顺序,因为它没有逻辑顺序。

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

我希望这会有所帮助。

于 2014-11-05T15:56:25.340 回答