TGViewer
Библиотека Go (Golang) разработчика Библиотека Go (Golang) разработчика @golang_lib · 2.7K subscribers
Post #707 727
☢️ Пакет unsafe: Взламываем систему типов Go

Пакет unsafe - это легальный способ сказать компилятору: «Отключи ремни безопасности, я беру управление на себя». С его помощью можно обходить строгую типизацию и напрямую управлять памятью, но любая ошибка приведет к моментальному падению сервиса (Segmentation Fault).

Проблема стандартной конвертации
В Go строки (string) иммутабельны (неизменяемы), а срезы байт ([]byte) можно менять. Когда вы пишете s := string(bytes), Go вынужден копировать всю память. Это делается для того, чтобы вы не смогли изменить исходный массив и случайно поменять символы в строке. В высоконагруженных местах (парсинг JSON, HTTP-роутеры) эти копирования плодят мусор и съедают CPU.

Zero-allocation конвертация (Go 1.20+)
Долгое время разработчики занимались черной магией, жонглируя внутренними структурами StringHeader и SliceHeader через указатели. С версии Go 1.20 в язык добавили элегантные функции unsafe.String и unsafe.Slice.


import "unsafe"

// Из []byte в string без копирования памяти
func BytesToString(b []byte) string {
if len(b) == 0 {
return ""
}
// Говорим Go: "Смотри на этот кусок памяти как на строку"
return unsafe.String(&b[0], len(b))
}

// Из string в []byte без аллокаций
func StringToBytes(s string) []byte {
if len(s) == 0 {
return nil
}
return unsafe.Slice(unsafe.StringData(s), len(s))
}



В чем смертельная опасность?
Вы обманули компилятор, но физика осталась прежней. Если вы превратили string в []byte с помощью unsafe, а затем попытались изменить этот срез (например, b[0] = 'X'), ваша программа мгновенно упадет. Строки часто хранятся в защищенной от записи секции памяти (read-only). Попытка записи туда вызывает панику на уровне операционной системы, которую невозможно перехватить через recover().

Когда это реально нужно?

• Написание сверхбыстрых логгеров (популярные библиотеки вроде zap или zerolog используют это под капотом).
• Парсинг потоковых сетевых протоколов, где вы просто читаете миллионы пакетов без их модификации.
• Только тогда, когда pprof явно показал, что функция runtime.slicebytetostring является главным узким местом приложения.

GC и устаревший API
Если вы поддерживаете легаси-код на старых версиях Go, где используется reflect.StringHeader с полем Data uintptr - срочно переписывайте. Garbage Collector в Go не видит связи между uintptr и реальным объектом в памяти. При неудачном тайминге GC мог очистить память, пока вы с ней работали. Новые методы unsafe.String сохраняют ссылочную целостность для сборщика мусора.

#golang #unsafe #performance #underhood #hardcore

📲 Мы в MAX

👉 @golang_lib
  • 👍 1
More from @golang_lib
  1. Sep 22, 2026🔴AI кодинг интервью с разработчиком из международного FinTech в четверг в 19:00 ДА! Вайбк…
  2. Sep 21, 2026📢 sync.Cond: Как разбудить 10 000 горутин одним вызовом (и не сломать планировщик) Предст…
  3. Sep 17, 2026🔎 pprof: Как найти функцию, которая жрет 80% CPU Сервис на проде внезапно упирается в пол…
  4. Sep 7, 2026🗺️ sync.Map: Почему эта «серебряная пуля» иногда пробивает дно производительности Как тол…
  5. Sep 1, 2026🔴 Тестовое собеседование с Go Senior с опытом работы в Яндексе, EPAM и Uzum в этот четвер…
  6. Sep 1, 2026Memory Alignment: Как сэкономить гигабайты RAM, просто поменяв строчки местами Вы написали…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →