Ответ
Нет, порядок итерации по map
в Go не гарантирован и не должен использоваться в логике программы.
Более того, начиная с Go 1.0, порядок итерации намеренно рандомизируется при каждом новом запуске программы. Это сделано для того, чтобы разработчики не полагались на случайный, но стабильный порядок, который может зависеть от реализации хеш-функции и внутренней структуры map
. Такое поведение помогает выявлять ошибки на ранних стадиях.
В некоторых версиях Go (например, после 1.12) поведение могло казаться более стабильным для малых карт в целях упрощения отладки, но это деталь реализации, на которую категорически нельзя полагаться.
Как итерироваться в определенном порядке?
Если требуется стабильный порядок обхода, необходимо:
- Получить все ключи из
map
и поместить их в слайс. - Отсортировать этот слайс.
- Итерироваться по отсортированному слайсу, получая значения из
map
по ключу.
Пример:
m := map[string]int{"c_key": 3, "a_key": 1, "b_key": 2}
// 1. Собираем ключи в слайс
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
// 2. Сортируем слайс ключей
sort.Strings(keys)
// 3. Итерируемся по отсортированным ключам
for _, k := range keys {
fmt.Printf("Ключ: %s, Значение: %dn", k, m[k])
}
// Вывод всегда будет отсортирован по ключу:
// Ключ: a_key, Значение: 1
// Ключ: b_key, Значение: 2
// Ключ: c_key, Значение: 3