Спецификация языка программирования Go говорит:
3. Порядок итерации по картам не указан. [...]
Этого следовало ожидать, поскольку тип карты может быть реализован в виде хеш-таблицы, или в виде дерева поиска, или в качестве некоторой другой структуры данных. Но как на самом деле map
реализован в Go?
Иными словами, что определяет порядок итераций ключей в
for k, _ := range m { fmt.Println(k) }
Я начал задумываться об этом после того, как увидел, что карта с string
ключами, очевидно, do имеет определенный порядок итераций. Программа типа
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
специализируется для целых чисел и для строк?