Проверяет понимание особенностей итерации по map в Go и причин отсутствия гарантированного порядка.
В Go map реализован как хеш-таблица. При добавлении элементов они распределяются по бакетам на основе хеша ключа. Порядок обхода зависит от внутреннего расположения данных, которое может меняться при перераспределении бакетов (rehashing).
Начиная с Go 1.0, разработчики языка намеренно сделали порядок итерации недетерминированным. При каждой итерации по map добавляется случайное смещение (random offset), чтобы подчеркнуть, что полагаться на порядок нельзя. Это предотвращает ошибки, когда код случайно зависит от текущего порядка, который может измениться в новой версии Go или на другом компьютере.
package main
import "fmt"
func main() {
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
// Порядок вывода будет разным при каждом запуске
for k, v := range m {
fmt.Println(k, v)
}
}Если нужен гарантированный порядок, нужно использовать отдельный слайс с ключами, отсортировать его и итерироваться по нему:
package main
import (
"fmt"
"sort"
)
func main() {
m := map[string]int{"b": 2, "a": 1, "c": 3}
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, m[k])
}
}Вывод: Не стоит полагаться на порядок итерации по map в Go. Если порядок важен, используйте сортировку ключей или другую структуру данных, например, слайс пар ключ-значение.