在围棋编程语言规范说:
3.未指定地图的迭代顺序。[…]
这是可以预期的,因为地图类型可以实现为哈希表,搜索树或其他某种数据结构。但是,如何map
在Go中实现呢?
换句话说,是什么决定了键的迭代顺序
for k, _ := range m { fmt.Println(k) }
我开始怀疑这个之后,我看到了地图string
键显然 也 有一定的迭代顺序。像这样的程序
package main
import ("fmt"; "time"; "rand")
func main() {
rand.Seed(time.Seconds())
words := [...]string{"foo", "bar", "a", "b", "c", "hello", "world",
"0", "1", "10", "100", "123"}
stringMap := make(map[string]byte)
for i := range rand.Perm(len(words)) {
stringMap[words[i]] = byte(rand.Int())
}
fmt.Print("stringMap keys:")
for k, _ := range stringMap { fmt.Print(" ", k) }
fmt.Println()
}
在我的机器上打印以下内容:
stringMap keys: a c b 100 hello foo bar 10 world 123 1 0
无论 插入顺序如何。
带有map[byte]byte
映射的等效程序也以随机顺序打印键,但是这里的键顺序 取决于 插入顺序。
如何实现所有这些?是map
专门用于整数和字符串吗?
Map在Go中作为哈希图实现。
Go运行时使用通用的hashmap实现,该实现在C中实现。map[string]T
和之间的唯一实现差异map[byte]T
是:哈希函数,等效函数和复制函数。
与(某些)C ++映射不同,Go映射并非完全专用于整数和字符串。
在 Go release.r60中
,只要没有键冲突,迭代顺序就与插入顺序无关。如果存在冲突,则迭代顺序受插入顺序影响。无论密钥类型如何,这都适用。在这方面,string
类型的键和类型的键之间没有区别byte
,因此,您的程序始终以相同的顺序打印字符串键只是一个巧合。除非修改映射,否则迭代顺序始终相同。
但是,在最新的 Go每周发行版中 (以及可能在本月发布的 Go1
中),迭代顺序是随机的(从伪随机选择的密钥开始,并且哈希码计算以伪随机形式作为种子)数)。如果使用每周发行版(以及Go1)编译程序,则每次运行程序时迭代顺序都会不同。就是说,无限次运行您的程序可能不会显示键集的所有可能排列。输出示例:
stringMap keys: b 0 hello c world 10 1 123 bar foo 100 a
stringMap keys: hello world c 1 10 bar foo 123 100 a b 0
stringMap keys: bar foo 123 100 world c 1 10 b 0 hello a
...
问题内容: 我有一个导航栏作为地图: 其中具有各种属性,子项等。当我尝试渲染导航栏(带有)时,它以随机顺序显示。我知道它在运行时会随机排序,但是似乎无法获取有序的键列表或按插入顺序进行迭代。 游乐场链接位于此处:http : //play.golang.org/p/nSL1zhadg5,尽管它似乎没有表现出相同的行为。 如何在不破坏插入顺序的情况下迭代此映射? 问题答案: Go地图不保持插入顺序;
问题内容: SQL标准是否为多表查询指定锁定顺序? 例如,给定: SQL标准是保证锁定顺序还是由(特定于实现的)执行计划确定? 有没有办法保证锁定顺序? 如果没有办法保证锁定顺序,我们应该如何防止死锁? 更新 :在未解释您的推理之前,请不要投票结束该问题。就我而言,这是一个编程问题,这使Stackoverflow变得非常重要。如果您认为这个问题需要进一步完善,请解释一下,我们非常乐意为您解答。 问
问题内容: 上面的go代码仅打印一次map [string] string三次。 我希望它具有固定的输出,但它显示如下: 变了! 而在python中: 输出: 问题答案: 您不能依靠获得密钥的顺序。语言规范说: “一个映射是一组无序的元素”,后来又说: “未指定映射的迭代顺序,并且不能保证每次迭代之间都相同。”
问题内容: 在python中,我编写了此函数来告诉自己如何在python中工作: 然后我用 这是我的Python解释器打印的输出: 为什么即使我先将a2输入到函数中,for循环也还是在a2之前打印a3值? 问题答案: 是一本字典。字典是无序的- 简而言之,未指定顺序和实现细节。深入了解之下,该顺序将根据项目的哈希值,插入顺序等而发生巨大变化,因此最好不要依赖与之相关的任何内容。
问题内容: 我担心给出的文件和目录的顺序。如果我有这些目录,,,,,,,,,,,,,什么是输出列表的顺序? 它是按数值排序的吗? 或按ASCII值排序,如? 此外,如何获得特定的排序? 问题答案: 用途。这是的文档字符串: listdir(路径)-> list_of_strings 返回一个列表,其中包含目录中条目的名称。 该列表按任意顺序排列 。它不包括特殊条目“。” 和“ ..”,即使它们存在
问题内容: 我有一个HashMap,每次我获得迭代器时,我都希望以不同的随机顺序迭代它们的键值对。从概念上讲,我想在调用迭代器之前对地图进行“混洗”(或者,如果需要,可以对迭代器进行“混洗”)。 我有两种选择: 1)使用LinkedHashMap的方法,并在内部保留条目列表,将其随机洗净,并在调用迭代器时返回该视图。 2)使用map.entrySet(),构造一个ArrayList并在其上使用sh