💡 Структуры в Go: под капотом они интереснее, чем кажется
На первый взгляд
- Почему структура занимает больше памяти, чем сумма её полей?
- Почему одни структуры можно сравнивать и использовать как ключ в
🗄️ Память, выравнивание и паддинг
Go хранит поля в памяти в порядке объявления. Чтобы данные были выровнены по границам процессора, компилятор добавляет "пустые байты" — padding.
Хотя тут одинаково, в больших структурах порядок полей может сэкономить десятки байт.
👉 Лайфхак: ставьте "тяжёлые" типы (int64, float64) выше "лёгких" (bool, byte), чтобы сократить паддинг.
⚖️ Сравнимость и ключи в map
Структуры можно сравнивать (==) и использовать как ключи в map, если все поля сравнимые.
✅ Как обойти:
Использовать фиксированный массив:
Или хранить хэш (uint64, строка) вместо самого среза.
📌 Вывод: структуры в Go — это не только про хранение данных. Зная про выравнивание и правила сравнимости, можно писать код, который будет и эффективным по памяти, и удобным в работе с map.
#golang #struct #memory #map
На первый взгляд
struct
— это просто контейнер с полями. Но стоит углубиться, и появляются вопросы: - Почему структура занимает больше памяти, чем сумма её полей?
- Почему одни структуры можно сравнивать и использовать как ключ в
map
, а другие — нет? 🗄️ Память, выравнивание и паддинг
Go хранит поля в памяти в порядке объявления. Чтобы данные были выровнены по границам процессора, компилятор добавляет "пустые байты" — padding.
type A struct {
B bool // 1 byte (+7 padding)
I int64 // 8 bytes
}
// Sizeof(A) = 16
type B struct {
I int64 // 8 bytes
B bool // 1 byte (+7 padding)
}
// Sizeof(B) = 16
Хотя тут одинаково, в больших структурах порядок полей может сэкономить десятки байт.
👉 Лайфхак: ставьте "тяжёлые" типы (int64, float64) выше "лёгких" (bool, byte), чтобы сократить паддинг.
⚖️ Сравнимость и ключи в map
Структуры можно сравнивать (==) и использовать как ключи в map, если все поля сравнимые.
type KeyGood struct {
ID int
Name string
}
// сравнимо, работает как ключ
type KeyBad struct {
Data []byte
}
// ошибка: []byte несравнимый тип
✅ Как обойти:
Использовать фиксированный массив:
type KeyArr struct { Digest [16]byte }
Преобразовать срез в строку:
key := string(digestBytes)
m := map[string]string{key: "value"}
Или хранить хэш (uint64, строка) вместо самого среза.
📌 Вывод: структуры в Go — это не только про хранение данных. Зная про выравнивание и правила сравнимости, можно писать код, который будет и эффективным по памяти, и удобным в работе с map.
#golang #struct #memory #map
❤17🔥4👍1🥰1