Постквантовая криптография, UUID из коробки и поиск «зависших» фоновых процессов — что нового в Go 1.27

Go 1.27 получил одно из крупнейших обновлений языка за последние годы.


szru5lko5oom1kd5m05org018tihijz6.jpg

Go долго сохранял репутацию языка, где простота и читаемость важнее синтаксических сокращений. Выпущенный 19 августа Go 1.27 заметно расширяет возможности языка: методы получили собственные параметры типа, компилятор стал лучше определять типы без подсказок программиста, работа со структурами упростилась, а стандартная библиотека обзавелась новым механизмом обработки JSON, постквантовыми подписями и поддержкой UUID. Команда Go сохранила совместимость в рамках Go 1, поэтому почти весь существующий код должен продолжить собираться и работать без изменений.

Поддержка обобщённого программирования появилась в Go 1.18 в 2022 году. Параметры типа тогда разрешили для функций и пользовательских типов, однако отдельный метод не мог объявить собственный новый параметр типа. Go 1.27 снимает ограничение и позволяет создавать методы, работающие с дополнительными типами без вынесения логики в отдельную функцию уровня пакета.

Хороший пример появился в стандартном генераторе случайных чисел math/rand/v2 . Раньше тип Rand предлагал отдельные методы Int32N, Int64N и IntN для разных разновидностей целых чисел. В Go 1.27 разработчики добавили универсальный метод N, способный работать с различными целочисленными типами. Программисту больше не приходится создавать несколько почти одинаковых методов только из-за различий в типах данных.

Новый механизм сохраняет ряд ограничений. Методы интерфейсов не могут объявлять собственные параметры типа, а метод с параметрами типа не может служить реализацией обычного метода интерфейса. Разработчики Go выбрали осторожный вариант расширения языка, чтобы не усложнять систему типов сильнее необходимого.

Go 1.27 также сокращает код при создании структур. Ключом в литерале структуры теперь может выступать допустимый селектор поля. Разработчик может напрямую задать значение поля встроенной структуры при создании родительского объекта, не описывая вручную каждый промежуточный уровень. Изменение особенно удобно при работе с глубоко вложенными структурами.

Компилятор одновременно научился лучше выводить типы для обобщённых функций. Раньше в некоторых ситуациях разработчику приходилось явно указывать аргументы типа. Новая версия способна самостоятельно определить подходящий тип при помещении обобщённой функции в составной литерал, преобразовании к функциональному типу или отправке функции через канал.

Изменения затронули не только синтаксис. Команда Go расширила go fix средствами автоматической модернизации старого кода, научила go doc принимать запросы вида package@version, а go mod tidy теперь приводит несколько блоков require в go.mod к стандартной структуре из прямых и косвенных зависимостей.

Компилятор получил специализированные функции выделения памяти для небольших объектов размером менее 80 байт. По данным разработчиков , стоимость некоторых операций выделения памяти снижается до 30%, хотя общий прирост производительности программ с большим количеством подобных операций ожидается примерно на уровне одного процента. Цена оптимизации составляет около 60 КБ дополнительного размера исполняемого файла.

В Go 1.27 появилась полноценная диагностика утечек горутин (goroutine). Профиль goroutineleak, экспериментально представленный в Go 1.26, вошёл в обычный runtime/pprof. Среда выполнения может находить горутины, навсегда заблокированные на каналах, sync.Mutex, sync.Cond и некоторых других механизмах синхронизации. Новый инструмент не гарантирует обнаружение всех возможных случаев, но упрощает поиск целого класса ошибок, которые раньше приходилось диагностировать другими способами.

Одно из крупнейших обновлений стандартной библиотеки касается JSON. Новый пакет encoding/json/v2 предлагает более гибкие настройки сериализации и разбора, а низкоуровневый encoding/json/jsontext предназначен для потоковой обработки JSON. Старый encoding/json теперь использует новую реализацию внутри, сохраняя прежнее поведение ради совместимости. Разработчики Go сообщают о заметном ускорении десериализации, тогда как скорость сериализации в целом осталась близкой к прежней. Переход на новый интерфейс не обязателен.

В стандартную библиотеку вошёл пакет crypto/mldsa с реализацией постквантовой схемы цифровой подписи ML-DSA из стандарта FIPS 204. Поддержка ML-DSA появилась также в X.509 и TLS 1.3. Новый пакет uuid позволяет создавать и разбирать UUID без сторонней зависимости. Экспериментальный simd предоставляет переносимые векторные операции с использованием аппаратных инструкций, а simd/archsimd получил поддержку ARM64 Neon и WebAssembly наряду с AMD64.

Обновление потребует внимания от владельцев старых Mac. Go 1.27 больше не поддерживает версии macOS старше macOS 13 Ventura. Для большинства остальных проектов разработчики ожидают беспроблемный переход благодаря политике обратной совместимости Go 1.

Расширение обобщённого программирования одновременно возвращает старую дискуссию о главном преимуществе Go. Язык создавался с расчётом на код, который легко читать и сопровождать, даже если ради понятности программисту приходится писать больше строк. Более выразительные обобщения уменьшают дублирование, но добавляют новые уровни абстракции, поэтому часть разработчиков опасается постепенного усложнения Go.

Спор стал особенно актуален на фоне распространения генеративного ИИ. В опубликованном 11 августа материале Google представители компании назвали читаемость, строгую типизацию и единообразие кода важными преимуществами при работе с ИИ-агентами. По версии Google, скорость ручного написания кода постепенно теряет прежнее значение, а основная нагрузка смещается в сторону проверки, сопровождения и поиска ошибок в автоматически созданных программах. Go 1.27 пытается совместить две задачи: убрать лишнее повторение кода и сохранить простоту, вокруг которой язык строился с самого начала.