3.2Kпросмотров
97.3%от подписчиков
16 декабря 2025 г.
Score: 3.5K
map[T]struct{} В отличие от питона и джавы, в го нет «родного» типа «множество» (set). Поэтому разработчики наловчились использовать вместо него map[T]struct{}: set := make(map[string]struct{})
set["apple"] = struct{}{}
if _, exists := set["apple"]; exists { fmt.Println("✓ apple")
} ✓ apple Прелесть использования struct{} в том, что у такой карты значения буквально занимают 0 байт. Но в Go 1.24 пришли швейцарские карты и случился потряс устоев. map[T]struct{} теперь занимает ровно столько же памяти, сколько и map[T]bool. На значениях больше не сэкономить. Дело в том, что в старых картах значения хранились отдельно от ключей: в каждом бакете сначала все ключи, потом все значения: [K1, K2... K8] [V1, V2... V8] Компилятор видел struct{}, и не выделял под значения память. В новых картах ключи и значения объединены в одну структуру (слот): [ {K1, V1}, {K2, V2}, ... ] Внутри слот выглядит так: struct { key keyType elem elemType
} По правилам компилятора, если структура заканчивается полем нулевого размера, этому полю все равно выделяется 1 байт (на случай, если какой-нибудь злодей создаст на него указатель). Таким образом, поле elem типа struct{} будет занимать 1 байт — точно так же, как bool. А весь слот — аж 16 байт, из-за паддинга (если ключ 8 байт). Прощай, микро-оптимизация. P.S. Прочитал я это у Артема Голубина, за что ему большое спасибо. P.P.S. Разработчики в курсе проблемы, но в 1.26 фикс не войдет.