Последний релиз Go, версия 1.26, выходит в феврале 2026 года, спустя шесть месяцев после Go 1.25. Большинство изменений касаются инструментов сборки, среды исполнения и библиотек. Как и раньше, релиз сохраняет совместимость с обещаниями Go 1. Ожидается, что почти все программы на Go продолжат компилироваться и выполняться аналогично предыдущим версиям.
Изменения в языке
Встроенная функция new, создающая новую переменную, теперь допускает в качестве аргумента выражение, задающее начальное значение переменной.
Эта возможность особенно полезна при работе с пакетами сериализации, такими как encoding/json или Protocol Buffers, которые используют указатель для представления необязательного значения, поскольку позволяет заполнить необязательное поле простым выражением:
import "encoding/json"
type Person struct {
Name string `json:"name"`
Age *int `json:"age"` // возраст, если известен; иначе nil
}
func personJSON(name string, born time.Time) ([]byte, error) {
return json.Marshal(Person{
Name: name,
Age: new(yearsSince(born)),
})
}
func yearsSince(t time.Time) int {
return int(time.Since(t).Hours() / (365.25 * 24)) // приблизительно
}
Снято ограничение, запрещавшее обобщённому типу ссылаться на самого себя в списке своих параметров типа. Теперь можно задавать ограничения типов, ссылающиеся на обобщённый тип. Например, обобщённый тип Adder может требовать, чтобы он инстанцировался типом, подобным самому себе:
type Adder[A Adder[A]] interface {
Add(A) A
}
func algo[A Adder[A]](x, y A) A {
return x.Add(y)
}
Ранее ссылка на Adder в первой строке не допускалась. Помимо расширения возможностей ограничений типов, это изменение несколько упрощает правила спецификации для параметров типов.
Инструменты
Команда go
Знаковая команда go fix была полностью переработана и теперь является домом для модернизаторов Go. Она обеспечивает надёжный способ обновления кодовой базы Go до современных идиом и API стандартной библиотеки. Начальный набор модернизаторов включает десятки инструментов для использования новейших возможностей языка Go и библиотеки, а также инлайнатор на уровне исходного кода, позволяющий автоматизировать собственные миграции API с помощью директив //go:fix inline.
Переписанная команда go fix построена на том же фреймворке анализа Go, что и go vet. Это означает, что одни и те же анализаторы, которые предоставляют диагностику в go vet, могут использоваться для предложения и применения исправлений в go fix. Исторические фиксеры команды go fix, все из которых были устаревшими, были удалены.
go mod init теперь по умолчанию использует более низкую версию go в новых файлах go.mod. Запуск go mod init с инструментарием версии 1.N.X создаст файл go.mod с версией Go go 1.(N-1).0. Предрелизные версии 1.N будут создавать файлы go.mod с указанием go 1.(N-2).0. Например, кандидаты в релиз Go 1.26 создадут файлы go.mod с go 1.24.0, а Go 1.26 и его минорные релизы — с go 1.25.0. Это призвано поощрять создание модулей, совместимых с текущими поддерживаемыми версиями Go.
Команды cmd/doc и go tool doc были удалены. В качестве замены можно использовать go doc: он принимает те же флаги и аргументы и ведёт себя аналогично.
Pprof
Веб-интерфейс инструмента pprof, включаемый флагом -http, теперь по умолчанию отображает представление пламени (flame graph). Предыдущее графическое представление доступно в меню «View → Graph» или по адресу /ui/graph.
Среда исполнения (runtime)
Новый сборщик мусора
Сборщик мусора Green Tea, доступный ранее как эксперимент в Go 1.25, теперь включён по умолчанию после обработки отзывов.
Дизайн этого сборщика мусора улучшает производительность разметки и сканирования мелких объектов за счёт лучшей локальности и масштабируемости на несколько ядер CPU. Результаты бенчмарков варьируются, но ожидается снижение накладных расходов на сборку мусора примерно на 10–40% в реальных приложениях, активно использующих сборку мусора. Дальнейшие улучшения порядка 10% ожидаются на более новых платформах на базе amd64 (Intel Ice Lake или AMD Zen 4 и новее), поскольку сборщик мусора теперь использует SIMD-инструкции для сканирования мелких объектов, когда это возможно.
Новый сборщик мусора может быть отключён установкой переменной GOEXPERIMENT=nogreenteagc при сборке. Эта настройка отключения, как ожидается, будет удалена в Go 1.27.
Более быстрые cgo-вызовы
Базовые накладные расходы среды исполнения на cgo-вызовы сокращены примерно на 30%.
Рандомизация базового адреса кучи
На 64-битных платформах среда исполнения теперь рандомизирует базовый адрес кучи при запуске. Это улучшение безопасности, затрудняющее злоумышленникам предсказание адресов памяти и эксплуатацию уязвимостей при использовании cgo. Эта функция может быть отключена установкой GOEXPERIMENT=norandomizedheapbase64 при сборке.
Экспериментальный профиль утечек горутин
Новый тип профиля, сообщающий об утечках горутин, доступен как эксперимент. Новый тип профиля, названный goroutineleak в пакете runtime/pprof, может быть включён установкой GOEXPERIMENT=goroutineleakprofile при сборке. Включение эксперимента также делает профиль доступным в качестве эндпоинта net/http/pprof: /debug/pprof/goroutineleak.
Утечная горутина — это горутина, заблокированная на некотором примитиве синхронизации (каналы, sync.Mutex, sync.Cond и т.д.), который не может стать разблокированным. Среда исполнения обнаруживает утечные горутины с помощью сборщика мусора: если горутина G заблокирована на примитиве P, и P недостижим из какой-либо запускаемой горутины или из горутин, которые эти могут разблокировать, то P не может быть разблокирован, и горутина G никогда не проснётся.
Следующий пример демонстрирует реальную утечку горутин, которую можно выявить с помощью нового профиля:
type result struct {
res workResult
err error
}
func processWorkItems(ws []workItem) ([]workResult, error) {
ch := make(chan result)
for _, w := range ws {
go func() {
res, err := processWorkItem(w)
ch <- result{res, err}
}()
}
var results []workResult
for range len(ws) {
r := <-ch
if r.err != nil {
// Этот ранний выход может вызвать утечку горутин.
return nil, r.err
}
results = append(results, r.res)
}
return results, nil
}
Поскольку ch небуферизированный, если processWorkItems завершается раньше времени из-за ошибки, все оставшиеся горутины processWorkItem утекут. Вскоре после этого ch станет недостижим для всех других горутин, не связанных с утечкой, что позволит среде исполнения обнаружить и сообщить об утечных горутинах.
Реализация является готовой к продакшну и считается экспериментом только в целях сбора отзывов об API. Планируется включить профили утечек горутин по умолчанию в Go 1.27.
Компилятор
Компилятор теперь может размещать хранилище данных срезов на стеке в большем количестве случаев, что повышает производительность. Если это изменение вызывает проблемы, можно воспользоваться инструментом bisect с флагом -compile=variablemake для поиска проблемного выделения. Все новые стековые выделения также можно отключить с помощью -gcflags=all=-d=variablemakehash=n.
Линкер
На 64-битном ARM Windows (windows/arm64) линкер теперь поддерживает внутренний режим связывания программ cgo, который можно запросить флагом -ldflags=-linkmode=internal.
Внесён ряд незначительных изменений в исполняемые файлы. Эти изменения не влияют на запущенные Go-программы, но могут затронуть программы, анализирующие Go-исполняемые файлы, а также пользователей внешнего режима связывания с пользовательскими скриптами линковки:
- Структура
moduledataтеперь размещена в собственном секции.go.module. - Поле
cutabструктурыmoduledataтеперь имеет правильную длину; ранее длина была в четыре раза больше. pcHeaderв начале секции.gopclntabбольше не записывает начало секции.text. Это поле теперь всегда равно нулю.- Секция
.gopclntabболее не содержит релокаций. На платформах с relro секция перемещена из сегмента relro в сегмент rodata. - Символы funcdata и findfunctab перемещены из секции
.rodataв.gopclntab. - Секция
.gosymtabудалена. - При использовании внутреннего режима связывания ELF-секции теперь отсортированы по адресу в заголовке.
Загрузчик (Bootstrap)
Go 1.26 теперь требует Go 1.24.6 или новее для загрузки. Ожидается, что Go 1.28 потребует минорный релиз Go 1.26 или новее.
Стандартная библиотека
Новый пакет crypto/hpke
Новый пакет crypto/hpke реализует гибридное шифрование открытым ключом (HPKE) в соответствии с RFC 9180, включая поддержку постквантовых гибридных KEM.
Новый экспериментальный пакет simd/archsimd
Go 1.26 вводит новый экспериментальный пакет simd/archsimd, который можно включить установкой переменной GOEXPERIMENT=simd при сборке. Этот пакет предоставляет доступ к архитектурно-зависимым SIMD-операциям. В настоящее время он доступен для архитектуры amd64 и поддерживает 128-, 256- и 512-битные векторные типы, такие как Int8x16 и Float64x8, с операциями вроде Int8x16.Add. API ещё не считается стабильным.
Планируется предоставить поддержку других архитектур в будущих версиях, но API намеренно архитектурно-зависим и, следовательно, не переносим.
Новый экспериментальный пакет runtime/secret
Новый пакет runtime/secret доступен как эксперимент, который можно включить установкой GOEXPERIMENT=runtimesecret при сборке. Он предоставляет механизм для безопасного стирания временных данных в коде, работающем с секретной информацией — как правило, криптографической, — таких как регистры, стек, новые выделения в куче. Этот пакет призван облегчить обеспечение прямой секретности. В настоящее время он поддерживает архитектуры amd64 и arm64 на Linux.
Go 1.26 — Незначительные изменения в библиотеке
bytes
Новый метод Buffer.Peek возвращает следующие n байтов из буфера без продвижения указателя чтения.
crypto
Новые интерфейсы Encapsulator и Decapsulator позволяют принимать абстрактные ключи инкапсуляции или деинкапсуляции KEM.
crypto/dsa
Параметр random в функции GenerateKey теперь игнорируется. Вместо этого теперь всегда используется безопасный источник криптографически случайных байтов. Для детерминированного тестирования используйте новую функцию testing/cryptotest.SetGlobalRandom. Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
crypto/ecdh
Параметр random в методе Curve.GenerateKey теперь игнорируется. Вместо этого теперь всегда используется безопасный источник криптографически случайных байтов. Для детерминированного тестирования используйте новую функцию testing/cryptotest.SetGlobalRandom. Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
Новый интерфейс KeyExchanger, реализуемый типом PrivateKey, позволяет принимать абстрактные приватные ключи ECDH, например, реализованные в аппаратном обеспечении.
crypto/ecdsa
Поля типа big.Int в структурах PublicKey и PrivateKey теперь устарели.
Параметр random в функциях GenerateKey, SignASN1, Sign и методе PrivateKey.Sign теперь игнорируется. Вместо этого теперь всегда используется безопасный источник криптографически случайных байтов. Для детерминированного тестирования используйте новую функцию testing/cryptotest.SetGlobalRandom. Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
crypto/ed25519
Если параметр random в функции GenerateKey равен nil, то GenerateKey теперь всегда использует безопасный источник криптографически случайных байтов вместо crypto/rand.Reader (который мог быть переопределён). Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
crypto/fips140
Криптографический модуль Go, соответствующий FIPS 140-3 v1.26.0 включает изменения, внесённые в пакеты crypto/internal/fips140/... вплоть до этого выпуска, и теперь может быть выбран с помощью GOFIPS140.
Новые функции WithoutEnforcement и Enforced позволяют работать в режиме GODEBUG=fips140=only, при этом выборочно отключая строгие проверки FIPS 140-3.
Функция Version возвращает разрешённую версию криптографического модуля Go, соответствующего FIPS 140-3, при сборке с замороженным модулем через GOFIPS140.
crypto/mlkem
Новые методы DecapsulationKey768.Encapsulator и DecapsulationKey1024.Encapsulator реализуют новый интерфейс crypto.Decapsulator.
Операции инкапсуляции и деинкапсуляции теперь выполняются примерно на 18% быстрее.
crypto/mlkem/mlkemtest
Новый пакет crypto/mlkem/mlkemtest предоставляет функции Encapsulate768 и Encapsulate1024, которые реализуют детерминизированную инкапсуляцию ML-KEM для использования в тестах на основе заранее известных ответов (known-answer tests).
crypto/rand
Параметр random в функции Prime теперь игнорируется. Вместо этого теперь всегда используется безопасный источник криптографически случайных байтов. Для детерминированного тестирования используйте новую функцию testing/cryptotest.SetGlobalRandom. Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
crypto/rsa
Новая функция EncryptOAEPWithOptions позволяет указывать различные функции хеширования для дополнения OAEP и генерации маски MGF1.
Параметр random в функциях GenerateKey, GenerateMultiPrimeKey и EncryptPKCS1v15 теперь игнорируется. Вместо этого теперь всегда используется безопасный источник криптографически случайных байтов. Для детерминированного тестирования используйте новую функцию testing/cryptotest.SetGlobalRandom. Новая настройка GODEBUG cryptocustomrand=1 временно восстанавливает старое поведение.
Если поля PrivateKey изменяются после вызова PrivateKey.Precompute, то PrivateKey.Validate теперь завершается ошибкой.
Поле PrivateKey.D теперь проверяется на согласованность с предвычисленными значениями, даже если оно не используется.
Небезопасное дополнение шифрования PKCS #1 v1.5 (реализуемое функциями EncryptPKCS1v15, DecryptPKCS1v15 и DecryptPKCS1v15SessionKey) теперь устарело.
crypto/sha3
Нулевое значение SHA3 теперь является пригодным для использования экземпляром SHA3-256, а нулевое значение SHAKE теперь является пригодным для использования экземпляром SHAKE256.
crypto/subtle
Функция WithDataIndependentTiming больше не привязывает вызывающую горутину к потоку ОС во время выполнения переданной функции. Кроме того, любые горутины, порождённые во время выполнения переданной функции, и их потомки теперь наследуют свойства WithDataIndependentTiming на время своего существования. Это изменение также затрагивает cgo следующим образом:
- Любой C-код, вызванный через cgo изнутри функции, переданной в
WithDataIndependentTiming, или из горутины, порождённой функцией, переданной вWithDataIndependentTiming, и её потомков, также будет иметь включённое независимое от данных время выполнения на протяжении вызова. Если C-код отключает независимое от данных время выполнения, оно будет повторно включено при возврате в Go. - Если C-код, вызванный через cgo — из функции, переданной в
WithDataIndependentTiming, или из любого другого места — включает или отключает независимое от данных время выполнения, то при вызове из Go это состояние сохраняется на протяжении вызова.
crypto/tls
Гибридные постквантовые обмены ключами SecP256r1MLKEM768 и SecP384r1MLKEM1024 теперь включены по умолчанию. Их можно отключить с помощью настройки Config.CurvePreferences или параметра GODEBUG tlssecpmlkem=0.
Новое поле ClientHelloInfo.HelloRetryRequest указывает, было ли сообщение ClientHello отправлено в ответ на сообщение HelloRetryRequest. Новое поле ConnectionState.HelloRetryRequest указывает, отправил ли сервер HelloRetryRequest или получил ли клиент HelloRetryRequest, в зависимости от роли соединения.
Тип QUICConn, используемый реализациями QUIC, включает новое событие для сообщения об ошибках рукопожатия TLS.
Если Certificate.PrivateKey реализует интерфейс crypto.MessageSigner, то его метод SignMessage используется вместо Sign в TLS 1.2 и выше.
Следующие настройки GODEBUG, введённые в Go 1.22 и Go 1.23, будут удалены в следующем мажорном выпуске Go. Начиная с Go 1.27, новое поведение будет применяться независимо от настройки GODEBUG или версии языка в go.mod:
tlsunsafeekm:ConnectionState.ExportKeyingMaterialбудет требовать TLS 1.3 или расширенное мастер-секрет (Extended Master Secret).tlsrsakex: устаревшие обмены ключами только на основе RSA без ECDH не будут включены по умолчанию.tls10server: минимальная версия TLS по умолчанию как для клиентов, так и для серверов будет TLS 1.2.tls3des: набор шифров по умолчанию не будет включать 3DES.x509keypairleaf: функцииX509KeyPairиLoadX509KeyPairвсегда будут заполнять полеCertificate.Leaf.
crypto/x509
Типы ExtKeyUsage и KeyUsage теперь имеют методы String, которые возвращают соответствующие имена OID, определённые в RFC 5280 и других реестрах.
Тип ExtKeyUsage теперь имеет метод OID, который возвращает соответствующий OID для EKU (Extended Key Usage).
Новая функция OIDFromASN1OID позволяет преобразовывать encoding/asn1.ObjectIdentifier в OID.
debug/elf
Определены дополнительные константы R_LARCH_* из LoongArch ELF psABI v20250521 (глобальная версия v2.40) для использования в системах на базе LoongArch.
errors
Новая функция AsType является обобщённой (generic) версией функции As. Она типобезопасна, быстрее и, в большинстве случаев, удобнее в использовании.
fmt
Для неформатированных строк fmt.Errorf("x") теперь выделяет меньше памяти и в целом соответствует выделениям errors.New("x").
go/ast
Новая функция ParseDirective разбирает директивные комментарии — комментарии вида //go:generate. Инструменты для работы с исходным кодом могут поддерживать собственные директивные комментарии, и этот новый API должен помочь им реализовать общепринятый синтаксис.
Новое поле BasicLit.ValueEnd фиксирует точную конечную позицию литерала, так что метод BasicLit.End теперь всегда возвращает правильный ответ. (Ранее позиция вычислялся с помощью эвристики, которая была некорректной для многострочных литералов необработанных строк в файлах исходного кода Windows из-за удаления символов возврата каретки.)
Программы, обновляющие поле ValuePos у BasicLit, созданных парсером, могут также потребовать обновления или очистки поля ValueEnd для избежания незначительных различий в форматированном выводе.
go/token
Новый удобный метод File.End возвращает позицию конца файла.
go/types
Настройка GODEBUG gotypesalias, введённая в Go 1.22, будет удалена в следующем мажорном выпуске Go. Начиная с Go 1.27, пакет go/types всегда будет создавать тип Alias для представления псевдонимов типов, независимо от настройки GODEBUG или версии языка в go.mod.
image/jpeg
Кодер и декодер JPEG заменены на новые, более быстрые и точные реализации. Код, рассчитывающий на конкретные побитовые результаты кодера или декодера, может потребовать обновления.
io
ReadAll теперь выделяет меньше промежуточной памяти и возвращает минимально необходимый по размеру итоговый слайс. Функция работает примерно в два раза быстрее, при этом обычно выделяя примерно вдвое меньше общей памяти, с ещё большей выгодой для больших входных данных.
log/slog
Функция NewMultiHandler создаёт MultiHandler, который вызывает все переданные обработчики (Handlers). Метод Enabled возвращает true, если метод Enabled хотя бы одного из обработчиков возвращает true. Методы Handle, WithAttrs и WithGroup вызывают соответствующий метод у каждого из активных обработчиков.
net
Новые методы Dialer — DialIP, DialTCP, DialUDP и DialUnix — позволяют набирать соединение определённых типов сети с передачей значений контекста.
net/http
Новое поле HTTP2Config.StrictMaxConcurrentRequests управляет тем, следует ли открывать новое соединение, если существующее соединение HTTP/2 превысило свой лимит потоков.
Новый метод Transport.NewClientConn возвращает клиентское соединение с HTTP-сервером. Большинству пользователей следует продолжать использовать Transport.RoundTrip для отправки запросов — он управляет пулом соединений. NewClientConn полезен для пользователей, которым необходимо реализовать собственное управление соединениями.
Client теперь использует и устанавливает cookies, привязанные к URL-адресам, часть host которых совпадает с Реquest.Host, когда это доступно. Ранее всегда использовался host адреса подключения. Перенаправления ServeMux с завершающим слэшем теперь используют HTTP-статус 307 (Временное перенаправление) вместо 301 (Перемещено навсегда).
net/http/httptest
HTTP-клиент, возвращаемый методом Server.Client, теперь будет перенаправлять запросы к example.com и любым поддоменам на тестируемый сервер.
net/http/httputil
Поле конфигурации ReverseProxy.Director устарело в пользу ReverseProxy.Rewrite.
Злонамеренный клиент может удалить заголовки, добавленные функцией Director, обозначив их как заголовки перехода (hop-by-hop). Поскольку нет способа решить эту проблему в рамках API Director, в Go 1.20 был добавлен новый хук Rewrite. Хуки Rewrite получают как неизменённый входящий запрос, полученный прокси, так и исходящий запрос, который будет отправлен прокси.
Поскольку хук Director принципиально небезопасен, мы теперь помечаем его как устаревший.
net/netip
Новый метод Prefix.Compare сравнивает два префикса.
net/url
Parse теперь отклоняет неправильно сформированные URL-адреса, содержащие двоеточия в компоненте хоста, такие как http://::1/ или http://localhost:80:80/. URL-адреса, содержащие адреса IPv6 в квадратных скобках, такие как http://[::1]/, по-прежнему принимаются. Новая настройка GODEBUG urlstrictcolons=0 восстанавливает старое поведение.
os
Новый метод Process.WithHandle обеспечивает доступ к внутреннему дескриптору процесса на поддерживаемых платформах (pidfd в Linux 5.4 или новее, Handle в Windows).
В Windows параметр flag функции OpenFile теперь может содержать любую комбинацию специфических для Windows флагов файлов, таких как FILE_FLAG_OVERLAPPED и FILE_FLAG_SEQUENTIAL_SCAN, для управления поведением кэширования файлов или устройств, режимами доступа и другими специальными флагами.
os/signal
NotifyContext теперь отменяет возвращаемый контекст с помощью context.CancelCauseFunc и ошибки, указывающей, какой сигнал был получен.
reflect
Новые методы Type.Fields, Type.Methods, Type.Ins и Type.Outs возвращают итераторы по полям типа (для структурного типа), методам, входным и выходным параметрам (для функционального типа) соответственно.
Аналогично, новые методы Value.Fields и Value.Methods возвращают итераторы по полям или методам значения соответственно. Каждая итерация предоставляет информацию о типе (StructField или Method) поля или метода вместе со значением (Value) поля или метода.
runtime/metrics
Добавлено несколько новых метрик планировщика, включая количество горутин в различных состояниях (ожидающих, исполняемых и т.д.) с префиксом /sched/goroutines, количество потоков ОС, известных рантайму, по адресу /sched/threads:threads, и общее количество горутин, созданных программой, по адресу /sched/goroutines-created:goroutines.
testing
Новые методы T.ArtifactDir, B.ArtifactDir и F.ArtifactDir возвращают каталог для записи выходных файлов тестов (артефактов).
Когда флаг -artifacts передан в go test, этот каталог будет располагаться внутри каталога вывода (указанного с помощью -outputdir или текущего каталога по умолчанию). В противном случае артефакты сохраняются во временном каталоге, который удаляется после завершения теста.
Первый вызов ArtifactDir при использовании -artifacts записывает расположение каталога в журнал теста.
Например, в тесте с именем TestArtifacts вызов t.ArtifactDir() выводит:
=== ARTIFACTS TestArtifacts /path/to/artifact/dir
Метод B.Loop больше не предотвращает встраивание (inlining) в теле цикла, что могло приводить к неожиданным выделениям памяти и замедлению бенчмарков. Благодаря этому исправлению мы ожидаем, что все бенчмарки могут быть переведены со старого стиля B.N на новый стиль B.Loop без каких-либо негативных последствий. Внутри тела цикла for b.Loop() { ... } параметры вызова функций, возвращаемые значения и присваиваемые переменные по-прежнему удерживаются в живости, что не позволяет компилятору оптимизировать целые части бенчмарка.
testing/cryptotest
Новая функция SetGlobalRandom настраивает глобальный, детерминированный источник криптографической случайности на время теста. Она влияет на crypto/rand и все неявные источники криптографической случайности в пакетах crypto/....
time
Настройка GODEBUG asynctimerchan, введённая в Go 1.23, будет удалена в следующем мажорном выпуске Go. Начиная с Go 1.27, пакет time всегда будет использовать небуферизированные (синхронные) каналы для таймеров, независимо от настройки GODEBUG или версии языка в go.mod.
Читайте также:
Комментариев нет:
Отправить комментарий