Go 1.26 вышел в феврале 2026 года, спустя полгода после Go 1.25. Это крупный релиз: он меняет правила игры в runtime (рантайме -- среде исполнения), добавляет давно ожидаемый синтаксический сахар в язык и приносит сразу несколько новых пакетов стандартной библиотеки, в том числе экспериментальных. Ниже -- разбор изменений с практическими примерами. Минимальная версия для сборки компилятора (bootstrap -- начальная загрузка) поднялась до Go 1.24.6.
Эта статья дополняет общий обзор релиза в файле 6.go126.md: здесь акцент на практике -- что именно поменялось в коде, который вы пишете каждый день.
Языковые изменения
new() теперь принимает выражение
Раньше встроенная функция new (new -- «создать новый») принимала только тип и возвращала указатель на его нулевое значение (zero value -- значение по умолчанию). Чтобы получить указатель на конкретное значение, приходилось заводить вспомогательную переменную или дженерик-хелпер.
// Go 1.25 и раньше: указатель на значение через временную переменную
age := 42
p := &age // *int, указывающий на 42
// Либо через дженерик-хелпер, который многие копировали из проекта в проект
func ptr[T any](v T) *T { return &v }
p2 := ptr(42)
В Go 1.26 new принимает произвольное выражение и сразу возвращает указатель на его значение:
// Go 1.26: указатель на значение одним вызовом
p := new(42) // *int, указывающий на 42
s := new("hello") // *string
t := new(time.Now()) // *time.Time
Это особенно удобно в структурах с опциональными (необязательными) полями-указателями, например при сериализации в JSON:
type User struct {
Name string
Age *int // указатель отличает "0 лет" от "поле не задано"
}
func makeUser(name string, born time.Time) User {
return User{
Name: name,
Age: new(yearsSince(born)), // никаких временных переменных
}
}
Важная деталь: выражение вычисляется один раз, и Go копирует результат в свежую область памяти (allocation -- выделение памяти). Это полноценная замена сотням мелких хелперов ptr[T], которые жили в каждом втором проекте.
Самоссылающиеся generics (дженерики)
Параметр типа (type parameter -- параметр-тип) теперь может ссылаться сам на себя в своём же списке ограничений (constraints -- ограничения). Это снимает старое ограничение компилятора и открывает чистый способ описывать рекурсивные API.
// Ограничение, ссылающееся на собственный параметр типа
type Adder[A Adder[A]] interface {
Add(A) A
}
// Теперь можно писать обобщённые алгоритмы над "самозамкнутыми" типами
func Sum[A Adder[A]](items []A) A {
var acc A
for _, x := range items {
acc = acc.Add(x)
}
return acc
}
Главная практическая польза -- типобезопасные fluent-builder'ы (текучие построители) и рекурсивные структуры данных, где метод должен возвращать именно конкретный тип наследника, а не абстрактный интерфейс:
// Builder (построитель), который возвращает свой же конкретный тип
type Builder[B Builder[B]] interface {
With(key, value string) B
}
Раньше такие конструкции либо не компилировались, либо требовали обходных хитростей с пустыми интерфейсами и приведением типов (type assertion -- утверждение о типе).
Runtime (рантайм) и производительность
Green Tea GC включён по умолчанию
Сборщик мусора (garbage collector -- сборщик мусора) под кодовым именем Green Tea («зелёный чай»), который в Go 1.25 был экспериментальным, в Go 1.26 стал работать по умолчанию. По официальным данным он снижает накладные расходы GC на 10--40%, а на новых процессорах amd64 (Intel Ice Lake, AMD Zen 4 и новее) даёт дополнительно около 10%.
Ничего менять в коде не нужно -- ускорение приходит само после обновления. Если новый GC по каким-то причинам мешает (например, нашли регрессию), его можно временно отключить:
# Вернуться к старому сборщику мусора
GOEXPERIMENT=nogreenteagc go build ./...
Подробный разбор внутреннего устройства Green Tea GC (регионы, generational hint -- поколенческая подсказка) есть в файле 6.go126.md. Здесь важно запомнить главное: это поведение по умолчанию, и оно бесплатно для разработчика.
Рандомизация базового адреса heap (кучи)
На 64-битных платформах рантайм теперь рандомизирует (случайно сдвигает) базовый адрес heap (кучи -- области динамической памяти) при старте программы. Это мера безопасности, аналог ASLR (Address Space Layout Randomization -- рандомизация размещения адресного пространства): атакующему сложнее предсказать, где в памяти лежат объекты, и эксплуатировать уязвимости с прямой работой с адресами.
# Отключить рандомизацию (например, для воспроизводимых дампов памяти при отладке)
GOEXPERIMENT=norandomizedheapbase64 go run ./...
Для большинства приложений это прозрачно. Внимание стоит обратить лишь тем, кто завязан на стабильность адресов между запусками (отладка, фаззинг с записью адресов).
Ускорение вызовов cgo на ~30%
cgo (мост между Go и C-кодом) исторически был «дорогим»: каждый переход из Go в C и обратно требовал переключения стека и синхронизации с планировщиком (scheduler -- планировщик горутин). В Go 1.26 базовые накладные расходы на вызов cgo снижены примерно на 30%.
Это особенно заметно в коде, который часто дёргает C-библиотеки в горячем цикле (hot loop -- горячий цикл):
/*
#include <math.h>
*/
import "C"
// Такой цикл с частыми вызовами C-функций в Go 1.26 заметно быстрее
func sumSqrt(values []float64) float64 {
var total float64
for _, v := range values {
total += float64(C.sqrt(C.double(v)))
}
return total
}
Оговорка остаётся прежней: cgo по-прежнему дороже чистого Go, и если вызов можно сделать на чистом Go, это почти всегда выгоднее. Но для тех, кто вынужден работать с нативными библиотеками, выигрыш ощутимый.
Выделение слайсов на стеке в большем числе случаев
Компилятор стал умнее в escape-анализе (escape analysis -- анализ убегания значений из стека в кучу). Теперь backing array (подложку -- внутренний массив) слайса в большем числе ситуаций удаётся разместить на стеке (stack -- стек вызовов), а не в куче. Стековые выделения не нагружают GC и освобождаются автоматически при выходе из функции.
// Если слайс не "убегает" за пределы функции,
// его внутренний массив теперь чаще живёт на стеке -- 0 нагрузки на GC
func process(n int) int {
buf := make([]int, n) // в подходящих условиях -- стек, а не куча
for i := range buf {
buf[i] = i * i
}
return buf[n-1]
}
Управлять этим поведением можно через флаг компилятора (нужно крайне редко, в основном для бенчмарков):
go build -gcflags=all=-d=variablemakehash=n ./...
Инструменты
Обновлённый go fix -- дом «модернизаторов»
Команда go fix («исправить») полностью переработана. Раньше она занималась в основном миграцией старого кода времён Go 1.0. Теперь это центральное место для модернизаторов (modernizers -- инструменты обновления кода до современных идиом): десятки автоматических правок, приводящих код к актуальному стилю и новым API стандартной библиотеки.
# Прогнать модернизаторы по всему проекту
go fix ./...
Например, go fix может заменить устаревшие конструкции на современные эквиваленты (циклы по индексу -- на range по целому числу из Go 1.22, ручные проверки -- на хелперы из slices/maps и т.д.). Под капотом используется тот же фреймворк анализа, что и у go vet (vet -- «проверять»).
Дополнительно появился source-level inliner (встраивание на уровне исходного кода) через директиву //go:fix inline: автор библиотеки может пометить функцию как «встраиваемую», и go fix развернёт её вызовы в местах использования.
//go:fix inline
func Add(a, b int) int { return a + b } // go fix может заменить вызовы Add(x, y) на (x + y)
Новые пакеты стандартной библиотеки
crypto/hpke -- гибридное шифрование
Новый пакет crypto/hpke реализует HPKE (Hybrid Public Key Encryption -- гибридное шифрование с открытым ключом) по стандарту RFC 9180. HPKE объединяет три примитива в едином API: KEM (Key Encapsulation Mechanism -- механизм инкапсуляции ключа), KDF (Key Derivation Function -- функция выведения ключа) и AEAD (Authenticated Encryption with Associated Data -- аутентифицированное шифрование). На практике это сводит end-to-end (сквозное) шифрование к паре операций: запечатать (seal) и распечатать (open).
// Концептуально: отправитель запечатывает сообщение публичным ключом получателя,
// получатель распечатывает своим приватным ключом
ciphertext, enc, err := sender.Seal(recipientPublicKey, plaintext, aad)
plaintext, err := recipient.Open(enc, ciphertext, aad)
Пакет включает поддержку post-quantum (постквантовых) гибридных KEM, что важно для защиты от будущих квантовых атак.
simd/archsimd (экспериментальный) -- SIMD-операции
Экспериментальный пакет simd/archsimd даёт доступ к SIMD-инструкциям (Single Instruction, Multiple Data -- одна инструкция над многими данными) конкретной архитектуры процессора. На момент релиза поддерживается только amd64 с векторными типами на 128, 256 и 512 бит. SIMD позволяет обрабатывать сразу несколько чисел одной машинной инструкцией -- это ускоряет числодробилки: обработку изображений, аудио, матричные вычисления.
# Пакет за экспериментальным флагом
GOEXPERIMENT=simd go build ./...
Поскольку пакет экспериментальный, его API может измениться в следующих релизах -- использовать в продакшене пока рано.
runtime/secret (экспериментальный) -- безопасное стирание секретов
Экспериментальный пакет runtime/secret («секрет») решает тонкую проблему криптографии: после работы с секретными данными (ключами, паролями) их копии могут оставаться в регистрах процессора, на стеке и в куче. Стандартное обнуление переменной компилятор иногда выкидывает как «бесполезное». Этот пакет гарантирует безопасное стирание временных копий секрета, поддерживая forward secrecy (прямую секретность -- свойство, при котором утечка ключа сейчас не раскрывает прошлый трафик).
# Поддержка amd64 и arm64 на Linux, за экспериментальным флагом
GOEXPERIMENT=runtimesecret go build ./...
Краткая сводка
| Изменение | Где | Суть |
|---|---|---|
new(expr) |
язык | указатель на значение одним вызовом |
| самоссылающиеся generics | язык | рекурсивные типобезопасные API |
| Green Tea GC | runtime | по умолчанию, GC быстрее на 10--40% |
| рандомизация heap | runtime | защита по типу ASLR |
| cgo −30% | runtime | дешевле переходы Go↔C |
| слайсы на стеке | компилятор | меньше нагрузка на GC |
обновлённый go fix |
инструменты | автомодернизация кода |
crypto/hpke |
stdlib | гибридное шифрование RFC 9180 |
simd/archsimd |
stdlib (эксп.) | SIMD-векторизация на amd64 |
runtime/secret |
stdlib (эксп.) | безопасное стирание секретов |
Большинство улучшений производительности (Green Tea GC, cgo, стековые слайсы) приходят бесплатно -- достаточно пересобрать проект новым компилятором. Языковые новинки (new(expr), самоссылающиеся generics) и go fix стоит освоить сразу: они напрямую упрощают повседневный код.