пятница, 17 июля 2026 г.

Релиз Go 1.26

Последний релиз 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

Новые методы DialerDialIP, 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.


Читайте также:


пятница, 19 сентября 2025 г.

Релиз Go 1.25

Версия Go 1.25 выходит в августе 2025 года спустя шесть месяцев после выпуска Go 1.24. Большинство изменений касаются инструментов сборки, среды исполнения и библиотек. Как и раньше, релиз сохраняет совместимость с обещаниями Go 1 относительно поддержки совместимости. Ожидается, что почти все программы на Go будут продолжать компилироваться и выполняться аналогично предыдущим версиям.

Изменения в языке

В версии Go 1.25 отсутствуют изменения в самом языке программирования, влияющие на существующие программы. Однако спецификация языка была обновлена, убрав понятие базовых типов в пользу четкого описания типов.

Инструменты

Команда go

Опция -asan, используемая командой go build, теперь по умолчанию включает проверку утечек памяти при завершении программы. Если память, выделенная средствами C, не освобождается и не используется другим кодом, эта проверка выдаст ошибку. Проверку можно отключить, установив переменную окружения ASAN_OPTIONS=detect_leaks=0.

Теперь дистрибутив Go включает меньше предварительно собранных бинарников инструментов. Основные инструменты цепочки сборки, такие как компилятор и линкер, остаются включенными, однако дополнительные утилиты будут собираться и запускаться динамически командой go tool, когда это потребуется.

Новая директива ignore в файле go.mod позволяет игнорировать определенные каталоги командами go. Файлы внутри указанных каталогов и их подпапок не будут учитываться при обработке пакетов с шаблонами вроде all или ./..., хотя сами файлы останутся доступными в архивах модулей.

Команда go doc получила новую опцию -http, позволяющую запустить локальный сервер документации, открываемый автоматически в браузере.

Опция -m -json команды go version выводит структуру runtime/debug.BuildInfo в формате JSON.

Команда go теперь поддерживает модули, размещённые в подпапках репозиториев, благодаря синтаксису <meta name="go-import" content="root-path vcs repo-url subdir">, указывая, что путь модуля соответствует указанному пути подпапки репозитория.

Новый шаблонный паттерн пакета work выбирает пакеты рабочего пространства (ранее называемые основными модулями), включая либо единственный рабочий модуль в режиме модулей, либо группу рабочих пространств в рабочем пространстве.

При обновлении строки go в файлах go.mod или go.work команда больше не добавляет строку инструментальной цепи, фиксируя версию инструмента.

Утилита проверки кода go vet

Утилита go vet пополнилась новыми проверочными инструментами:

  • Анализатор waitgroup, выявляющий неправильное использование метода sync.WaitGroup.Add.
  • Анализатор hostport, предупреждающий о некорректном формировании адресов вида fmt.Sprintf("%s:%d", host, port) для функций типа net.Dial, поскольку это неправильно работает с IPv6. Вместо этого рекомендуется использовать метод net.JoinHostPort.

Среда исполнения (runtime)

Контейнер-зависимый параметр

По умолчанию значение параметра GOMAXPROCS изменилось следующим образом:

  • В Linux среда исполнения рассматривает ограничение пропускной способности процессора контейнера, если оно установлено. Если предел ниже числа доступных ядер, GOMAXPROCS принимает минимальное значение. Это особенно актуально для контейнерных сред вроде Kubernetes, где ограничения ЦПУ соответствуют настройкам "лимит ЦПУ". Параметр "запросы ЦПУ" системой не учитывается.
  • Во всех операционных системах среда периодически обновляет значение GOMAXPROCS, если изменяется число доступных ядер или лимит пропускной способности контейнера.

Эти настройки отключаются вручную, если параметр GOMAXPROCS установлен заранее (через переменную окружения или методом runtime.GOMAXPROCS), либо принудительно через опции GODEBUG: containermaxprocs=0 и updatemaxprocs=0.

Чтобы поддерживать обновление лимитов контейнера, среда выполнения хранит кэшированные файловые дескрипторы для конфигурационных файлов группы управления (cgroups) на протяжении всего срока службы процесса.

Новый экспериментальный сборщик мусора

В Go 1.25 представлен новый экспериментальный сборщик мусора, который улучшает производительность разметки и сканирования мелких объектов посредством оптимизации размещения данных и эффективного использования ресурсов процессора. Предполагается уменьшение накладных расходов на сборку мусора примерно на 10–40%, особенно в приложениях, активно использующих сборку мусора.

Для активации нового сборщика необходимо задать переменную среды GOEXPERIMENT=greenteagc при сборке приложения. Ожидается дальнейшее развитие и улучшение дизайна сборщика, поэтому разработчики приглашаются к участию в экспериментах и обсуждению.

Запись трейсов на лету (Trace flight recorder)

Механизм трассировки выполнения, традиционно полезный, но дорогой ресурсоемкий инструмент, дополнен новым API runtime/trace.FlightRecorder. Он записывает трейсы выполнения программы в кольцевой буфер в памяти, позволяя сохранять трассировку в компактном виде. Приложение может вызвать метод FlightRecorder.WriteTo, чтобы записать последние секунды трейса в файл при возникновении значимых событий.

Размер и продолжительность сохраняемого трейса можно настроить через конфигурацию FlightRecorderConfig.

Изменение вывода сообщений паники

Отныне при выходе программы из-за необработанного восстановления паники (repanic) повтор сообщения паники устранён. Ранее вывод выглядел так:

panic: PANIC [recovered]
panic: PANIC

Теперь вывод выглядит проще:

panic: PANIC [recovered, repanicked]

Названия виртуальных областей памяти (VMA) на Linux

В Linux с поддержкой именования виртуальных областей памяти (VMA) Go автоматически аннотирует виртуальные участки памяти, используемые процессом, поясняя их назначение. Например, для кучи памяти будет создано имя вида [anon: Go: heap]. Аннотацию можно отключить через GODEBUG-параметр decoratemappings=0.

Компилятор

Ошибка с нулевым указателем

В Go 1.25 исправлена ошибка компилятора, появившаяся в Go 1.21, которая приводила к неправильному отложению проверки на ноль указателя. Следующая программа, работавшая ранее ошибочно, теперь корректно генерирует исключение:

package main
import "os"

func main() {
    f, err := os.Open("nonExistentFile")
    name := f.Name()
    if err != nil {
        return
    }
    println(name)
}

Проблема заключалась в том, что обращение к результатам вызова происходило до проверки ошибки. Если произошла ошибка открытия файла, указатель f мог оказаться пустым, вызывая исключение при обращении к нему. Теперь проверка производится сразу после возможного возникновения ошибки.

Поддержка формата DWARF5

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

Генерация DWARF 5 может быть отключена путем установки переменной окружения GOEXPERIMENT=nodwarf5 во время сборки (эта опция может быть удалена в будущих релизах Go).

Более быстрые срезы

Теперь компилятор способен выделять память для среза непосредственно на стеке в большем количестве случаев, что улучшает производительность. Это изменение потенциально усиливает эффект некорректного использования unsafe.Pointer. Для отслеживания проблем с такими ошибками можно воспользоваться инструментом bisect с флагом -compile=variablemake. Все новые стековые выделения памяти могут быть отключены с помощью опции -gcflags=all=-d=variablemakehash=n.

Линкер

Линкер теперь принимает новый аргумент командной строки -funcalign=N, задающий выравнивание точек входа функций. Значение по умолчанию зависит от платформы и остается неизменным в данном релизе.

Стандартная библиотека

Новый пакет testing/synctest

Новый пакет testing/synctest обеспечивает поддержку тестирования конкурентного кода. Метод Test запускает тестовую функцию внутри изолированного "пузыря". Внутри пузыря виртуализируется время: функции пакета time работают с фиктивными часами, и часы продвигаются вперед мгновенно, если все горутины заблокированы.

Метод Wait ожидает блокировки всех горутин текущего пузыря.

Этот пакет впервые появился в Go 1.24 под экспериментальной настройкой GOEXPERIMENT=synctest, однако тогда имел немного иной интерфейс. Эксперимент теперь считается завершённым и доступен по умолчанию. Старая реализация доступна, если установлена настройка GOEXPERIMENT=synctest, но будет удалена в Go 1.26.

Новый экспериментальный пакет encoding/json/v2

Версия Go 1.25 включает новую экспериментальную реализацию обработки JSON, которую можно включить путём установки переменной среды GOEXPERIMENT=jsonv2 во время сборки.

При включении становятся доступными два новых пакета:

  • Пакет encoding/json/v2 представляет собой значительное обновление существующего пакета encoding/json.
  • Пакет encoding/json/jsontext предоставляет низкоуровневую обработку синтаксиса JSON.

Кроме того, при включённой настройке GOEXPERIMENT=jsonv2 поведение пакета encoding/json меняется следующим образом:

  • Использует новую реализацию JSON. Хотя поведение маршалинга и демаршалинга остаётся прежним, тексты ошибок, возвращаемых функциями пакета, могут отличаться.
  • Появляется ряд новых настроек, позволяющих конфигурировать процесс маршализации и демаршализации.

Новая реализация работает значительно лучше существующей во многих сценариях. В целом, производительность кодирования у обеих реализаций одинакова, а декодирование в новой реализации значительно быстрее. Более подробный анализ в репозитории github.com/go-json-experiment/jsonbench.

Пользователей пакета encoding/json настоятельно призывают протестировать свою программу с активированной настройкой GOEXPERIMENT=jsonv2, чтобы выявить возможные проблемы совместимости с новой реализацией.

Ожидается дальнейшее развитие дизайна пакета encoding/json/v2. Разработчикам рекомендуется попробовать новый API и оставить отзывы на странице предложений.

Незначительные изменения библиотеки

archive/tar

Реализация метода Writer.AddFS теперь поддерживает символические ссылки для файловых систем, реализующих интерфейс io/fs.ReadLinkFS. Это позволяет правильно обрабатывать символьные ссылки при архивировании файлов.

encoding/asn1

Методы Unmarshal и UnmarshalWithParams теперь обрабатывают типы ASN.1 T61String и BMPString более последовательно. Некоторые некорректные кодировки, которые раньше принимались, теперь будут отклоняться.

crypto

MessageSigner — это новый интерфейс подписи, который могут реализовать подписывающие стороны, желающие самостоятельно хешировать сообщение для подписи. Также представлена новая функция SignMessage, которая пытается обновить интерфейс подписчика до MessageSigner, используя метод MessageSigner.SignMessage в случае успеха и метод Signer.Sign в противном случае. Это можно использовать, когда коду требуется поддержка как Signer, так и MessageSigner.

Изменение параметра fips140 GODEBUG после запуска программы теперь не является операцией. Ранее это было задокументировано как недопустимое и могло вызвать панику.

SHA-1, SHA-256 и SHA-512 теперь работают медленнее на amd64 при отсутствии инструкций AVX2. Все серверные процессоры (и большинство других), выпущенные с 2015 года, поддерживают AVX2.

crypto/ecdsa

Введены новые методы для низкоуровневого представления ключей:

  • ParseRawPrivateKey: парсинг приватного ключа.
  • ParseUncompressedPublicKey: парсинг публичного ключа.
  • PrivateKey.Bytes: получение байтов приватного ключа.
  • PublicKey.Bytes: получение байтов публичного ключа.

Эти методы заменяют необходимость использования функций из пакетов crypto/elliptic и math/big.

При включении режима FIPS 140-3 подпись теперь выполняется в четыре раза быстрее, что сопоставимо с производительностью режима без FIPS.

crypto/ed25519

При включении режима FIPS 140-3 подпись теперь выполняется в четыре раза быстрее, что сопоставимо с производительностью режима без FIPS.

crypto/elliptic

Скрытые и недокументированные методы Inverse и CombinedMult в некоторых реализациях Curve были удалены.

crypto/rsa

PublicKey больше не утверждает, что значение модуля считается секретным. VerifyPKCS1v15 и VerifyPSS уже предупреждали, что все входные данные являются открытыми и могут быть раскрыты, а также существуют математические атаки, позволяющие восстановить модуль из других открытых значений.

Генерация ключей теперь в три раза быстрее.

crypto/sha1

Хеширование теперь выполняется в два раза быстрее на amd64 при наличии инструкций SHA-NI.

crypto/sha3

Новый метод SHA3.Clone реализует hash.Cloner.

Хеширование теперь в два раза быстрее на процессорах Apple M.

crypto/tls

Новое поле ConnectionState.CurveID раскрывает механизм обмена ключами, используемый для установления соединения.

Новый обратный вызов Config.GetEncryptedClientHelloKeys можно использовать для установки EncryptedClientHelloKeys для сервера, который будет использоваться при отправке клиентом расширения Encrypted Client Hello.

Алгоритмы подписи SHA-1 теперь запрещены в рукопожатиях TLS 1.2 в соответствии с RFC 9155. Их можно снова включить, настроив GODEBUG tlssha1=1.

При включенном режиме FIPS 140-3 в TLS 1.2 теперь требуется расширенный главный секрет, а Ed25519 и X25519MLKEM768 теперь разрешены.

Серверы TLS теперь предпочитают самую высокую поддерживаемую версию протокола, даже если она не является наиболее предпочтительной для клиента.

Клиенты и серверы TLS теперь более строго следуют спецификациям и отклоняют нестандартное поведение. Соединения с совместимыми одноранговыми узлами не должны быть затронуты.

crypto/x509

CreateCertificate, CreateCertificateRequest и CreateRevocationList теперь могут принимать интерфейсы подписи crypto.MessageSigner, а также crypto.Signer. Это позволяет этим функциям использовать подписывающие стороны, реализующие интерфейсы «однократной» подписи, где хеширование выполняется в рамках операции подписи, а не вызывающей стороной.

Certificate теперь использует усеченный SHA-256 для заполнения SubjectKeyId, если он отсутствует. Параметр GODEBUG x509sha256skid=0 возвращается к SHA-1.

ParseCertificate теперь отклоняет сертификаты, содержащие расширение BasicConstraints с отрицательным pathLenConstraint.

ParseCertificate теперь обрабатывает строки, закодированные с помощью типов ASN.1 T61String и BMPString, более согласованно. Это может привести к отклонению некоторых ранее принятых некорректных кодировок.

debug/elf

Пакет debug/elf добавляет две новые константы:

  • PT_RISCV_ATTRIBUTES
  • SHT_RISCV_ATTRIBUTES для анализа RISC-V ELF.

go/ast

Функции FilterPackage, PackageExports и MergePackageFiles, а также тип MergeMode и его константы устарели, поскольку предназначены только для использования с давно устаревшими механизмами Object и Package.

Новая функция PreorderStack, как и Inspect, обходит синтаксическое дерево и обеспечивает управление переходом в поддеревья, но для удобства она также предоставляет стек вложенных узлов в каждой точке.

go/parser

Функция ParseDir устарела.

go/token

Новый метод FileSet.AddExistingFiles позволяет добавлять существующие файлы в FileSet или создавать FileSet для произвольного набора файлов, устраняя проблемы, связанные с одним глобальным FileSet в долгоживущих приложениях.

go/types

У Var теперь есть метод Var.Kind, который классифицирует переменную как переменную уровня пакета, получателя, параметра, результата, локальной переменной или поля структуры.

Новая функция LookupSelection ищет поле или метод с заданным именем и типом получателя, как и существующая функция LookupFieldOrMethod, но возвращает результат в виде Selection.

hash

Новый интерфейс XOF может быть реализован с помощью «расширяемых функций вывода» — хэш-функций с произвольной или неограниченной длиной выходных данных, таких как SHAKE.

Хэши, реализующие новый интерфейс Cloner, могут возвращать копию своего состояния. Все реализации хэшей стандартной библиотеки теперь реализуют Cloner.

hash/maphash

Новый метод Hash.Clone реализует hash.Cloner.

io/fs

Новый интерфейс ReadLinkFS обеспечивает возможность чтения символических ссылок в файловой системе.

log/slog

GroupAttrs создаёт групповой атрибут Attr из среза значений Attr.

У записи теперь есть метод Source, возвращающий исходное местоположение или nil, если оно недоступно.

mime/multipart

Новая вспомогательная функция FileContentDisposition создает составные поля заголовка Content-Disposition.

net

LookupMX и Resolver.LookupMX теперь возвращают DNS-имена, которые выглядят как допустимые IP-адреса, а также допустимые доменные имена. Ранее, если сервер имен возвращал IP-адрес в качестве DNS-имени, LookupMX отклонял его, как того требуют RFC. Однако на практике серверы имен иногда возвращают IP-адреса.

В Windows ListenMulticastUDP теперь поддерживает адреса IPv6.

В Windows теперь возможно преобразование между os.File и сетевым подключением. В частности, теперь реализованы функции FileConn, FilePacketConn и FileListener, возвращающие сетевое подключение или прослушиватель, соответствующий открытому файлу. Аналогично, теперь реализованы методы File для TCPConn, UDPConn, UnixConn, IPConn, TCPListener и UnixListener, возвращающие базовый os.File сетевого подключения.

net/http

Новый CrossOriginProtection реализует защиту от подделки межсайтовых запросов (CSRF), отклоняя небезопасные запросы кросс-источника браузера. Он использует современные метаданные Fetch браузера, не требует токенов или файлов cookie и поддерживает обходы на основе источника и шаблона.

os

В Windows функция NewFile теперь поддерживает дескрипторы, открытые для асинхронного ввода-вывода (то есть в вызове syscall.CreateFile указывается syscall.FILE_FLAG_OVERLAPPED). Эти дескрипторы связаны с портом завершения ввода-вывода среды выполнения Go, что обеспечивает следующие преимущества для результирующего файла File:

  • Методы ввода-вывода (File.Read, File.Write, File.ReadAt и File.WriteAt) не блокируют поток ОС.
  • Поддерживаются методы Deadline (File.SetDeadline, File.SetReadDeadline и File.SetWriteDeadline).

Это улучшение особенно полезно для приложений, взаимодействующих через именованные каналы в Windows.

Обратите внимание, что дескриптор может быть связан только с одним портом завершения одновременно. Если дескриптор, предоставленный NewFile, уже связан с портом завершения, возвращаемый файл File понижается до режима синхронного ввода-вывода. В этом случае методы ввода-вывода блокируют поток ОС, а методы с ограничением по времени не действуют.

Файловые системы, возвращаемые DirFS и Root.FS, реализуют новый интерфейс io/fs.ReadLinkFS. CopyFS поддерживает символические ссылки при копировании файловых систем, реализующих io/fs.ReadLinkFS.

Тип Root поддерживает следующие дополнительные методы:

  • Root.Chmod
  • Root.Chown
  • Root.Chtimes
  • Root.Lchown
  • Root.Link
  • Root.MkdirAll
  • Root.ReadFile
  • Root.Readlink
  • Root.RemoveAll
  • Root.Rename
  • Root.Symlink
  • Root.WriteFile

reflect

Новая функция TypeAssert позволяет преобразовать значение Value напрямую в значение Go заданного типа. Это похоже на использование утверждения типа для результата Value.Interface, но позволяет избежать ненужного выделения памяти.

regexp/syntax

Синтаксисы классов символов \p{name} и \P{name} теперь поддерживают имена Any, ASCII, Assigned, Cn и LC, а также псевдонимы категорий Unicode, например, \p{Letter} для \pL. Следуя Unicode TR18, они также используют поиск имён без учёта регистра, игнорируя пробелы, подчёркивания и дефисы.

runtime

Функции очистки, запланированные AddCleanup, теперь выполняются одновременно и параллельно, что делает очистку более эффективной при интенсивном использовании, таком как уникальный пакет. Обратите внимание, что отдельные очистки по-прежнему должны перенаправлять свою работу в новую горутину, если они должны выполняться или блокироваться на длительное время, чтобы избежать блокировки очереди очистки.

Новый параметр GODEBUG=checkfinalizers=1 помогает выявлять распространённые проблемы с финализаторами и очистками, например, описанные в руководстве по сборке мусора. В этом режиме среда выполнения выполняет диагностику на каждом цикле сборки мусора, а также регулярно сообщает длину очереди финализаторов и очистки в stderr, что помогает выявлять проблемы с длительно выполняющимися финализаторами и/или очистками.

Новая функция SetDefaultGOMAXPROCS устанавливает для GOMAXPROCS значение по умолчанию среды выполнения, как если бы переменная окружения GOMAXPROCS не была установлена. Это полезно для включения нового значения GOMAXPROCS по умолчанию, если оно было отключено переменной среды GOMAXPROCS или предыдущим вызовом GOMAXPROCS.

runtime/pprof

Профиль мьютекса для конкуренции за внутренние блокировки во время выполнения теперь корректно указывает на конец критической секции, вызвавшей задержку. Это соответствует поведению профиля для конкуренции за значения sync.Mutex. Настройка runtimecontentionstacks для GODEBUG, которая позволяла включить необычное поведение Go 1.22–1.24 для этой части профиля, теперь удалена.

sync

Новый метод WaitGroup.Go делает общепринятую схему создания и подсчета горутин более удобной.

testing

Новые методы T.Attr, B.Attr и F.Attr выдают атрибут в тестовый журнал. Атрибут — это произвольная комбинация ключа и значения, связанная с тестом.

Например, в тесте с именем TestF метод t.Attr("key", "value") выдаёт:

=== ATTR  TestF key value

С флагом -json атрибуты отображаются как новое действие «attr».

Новый метод Output методов T, B и F предоставляет объект io.Writer, который записывает данные в тот же поток вывода теста, что и TB.Log. Как и в случае с TB.Log, вывод имеет отступ, но не включает номер файла и строки.

Функция AllocsPerRun теперь вызывает панику при запуске параллельных тестов. Результат AllocsPerRun изначально нестабилен при запуске других тестов. Новое поведение паники помогает выявлять такие ошибки.

testing/fstest

MapFS реализует новый интерфейс io/fs.ReadLinkFS. TestFS проверит функциональность интерфейса io/fs.ReadLinkFS, если он реализован. TestFS больше не будет следовать символическим ссылкам, чтобы избежать неограниченной рекурсии.

unicode

Новая карта CategoryAliases предоставляет доступ к псевдонимам категорий, например, «Letter» для «L».

Новые категории Cn и LC определяют неназначенные кодовые точки и буквы с регистром соответственно. Они всегда были определены в Unicode, но были случайно пропущены в более ранних версиях Go. Категория C теперь включает Cn, то есть в неё добавлены все неназначенные кодовые точки.

unique

Пакет unique теперь быстрее, эффективнее и параллельно восстанавливает интернированные значения. В результате приложения, использующие Make, теперь реже сталкиваются с перегрузкой памяти при интернировании большого количества действительно уникальных значений.

Для сбора переданных в Make значений, содержащих дескрипторы, ранее требовалось несколько циклов сборки мусора, пропорциональных глубине цепочки значений дескрипторов. Теперь, если они не используются, они быстро собираются за один цикл.

Порты

Darwin

Как было объявлено в примечаниях к релизу Go 1.24, для Go 1.25 требуется macOS 12 Monterey или более поздняя версия. Поддержка предыдущих версий прекращена.

Windows

Go 1.25 — последний релиз, содержащий неисправный 32-битный порт для Windows/ARM (GOOS=windows GOARCH=arm). Он будет удалён в Go 1.26.

Loong64

Порт linux/loong64 теперь поддерживает детектор гонок, собирая информацию трассировки из кода C с помощью runtime.SetCgoTraceback и связывая программы cgo в режиме внутренней компоновки.

RISC-V

Порт linux/riscv64 теперь поддерживает режим сборки плагина.

Переменная среды GORISCV64 теперь принимает новое значение rva23u64, которое выбирает профиль приложения пользовательского режима RVA23U64.


Читайте также:


купить игрушку gopher

вторник, 4 марта 2025 г.

Релиз Go 1.24

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

Изменения в языке

Go 1.24 теперь полностью поддерживает псевдонимы универсальных типов: псевдоним типа может быть параметризован как определенный тип. На данный момент эту функцию можно отключить, установив GOEXPERIMENT=noaliastypeparams; но настройка aliastypeparams будет удалена для Go 1.25.

Инструменты

Команда go

Модули Go теперь могут отслеживать зависимости исполняемых файлов с помощью директив инструментов в go.mod. Это устраняет необходимость в предыдущем обходном пути добавления инструментов в виде пустых импортов в файл, который обычно называется «tools.go». Команда go tool теперь может запускать эти инструменты в дополнение к инструментам, поставляемым с дистрибутивом Go.

Новый флаг -tool для go get приводит к добавлению директивы tool в текущий модуль для именованных пакетов в дополнение к добавлению директив require.

Новый меташаблон tool относится ко всем инструментам в текущем модуле. Это можно использовать для их обновления с помощью go get tool или для установки в каталог GOBIN с помощью go install tool.

Исполняемые файлы, созданные go run, и новое поведение go tool теперь кэшируются в кэше сборки Go. Это ускоряет повторные выполнения за счет увеличения кэша.

Команды go build и go install теперь принимают флаг -json, который сообщает о выходных данных сборки и сбоях в виде структурированного вывода JSON на стандартном выводе.

Кроме того, go test -json теперь сообщает о выходных данных сборки и сбоях в формате JSON, чередующемся с результатом теста JSON. Они различаются новыми типами действий, но если они вызывают проблемы в системе интеграции тестов, вы можете вернуться к текстовому выводу сборки с помощью настройки GODEBUG gotestjsonbuildtext=1.

Новая переменная среды GOAUTH обеспечивает гибкий способ аутентификации выборок частных модулей.

Команда go build теперь устанавливает версию основного модуля в скомпилированном двоичном файле на основе тега системы контроля версий и/или фиксации. Суффикс +dirty будет добавлен, если есть незафиксированные изменения. Используйте флаг -buildvcs=false, чтобы исключить информацию о контроле версий из двоичного файла.

Новая настройка GODEBUG toolchaintrace=1 может использоваться для отслеживания процесса выбора цепочки инструментов команды go.

Cgo

Cgo поддерживает новые аннотации для функций C для улучшения производительности во время выполнения. #cgo noescape cFunctionName сообщает компилятору, что память, переданная функции C cFunctionname, не экранируется. #cgo nocallback cFunctionName сообщает компилятору, что функция C cFunctionName не вызывает никаких функций Go.

В настоящее время Cgo отказывается компилировать вызовы функции C, которая имеет несколько несовместимых объявлений. Например, если f объявлена как void f(int) и void f(double), cgo сообщит об ошибке вместо того, чтобы, возможно, сгенерировать некорректную последовательность вызовов для f(0). Новое в этом релизе — лучший детектор для этого состояния ошибки, когда несовместимые объявления появляются в разных файлах.

Objdump

Инструмент objdump теперь поддерживает дизассемблирование на 64-битных LoongArch (GOARCH=loong64), RISC-V (GOARCH=riscv64) и S390X (GOARCH=s390x).

Vet

Новый анализатор тестов сообщает о распространенных ошибках в объявлениях тестов, фаззеров, бенчмарков и примеров в тестовых пакетах, таких как неправильно сформированные имена, неверные подписи или примеры, которые документируют несуществующие идентификаторы. Некоторые из этих ошибок могут привести к тому, что тесты не будут запускаться. Этот анализатор входит в подмножество анализаторов, которые запускаются go test.

Существующий анализатор printf теперь сообщает о диагностике для вызовов формы fmt.Printf(s), где s — это строка непостоянного формата без других аргументов. Такие вызовы почти всегда являются ошибкой, так как значение s может содержать символ %; вместо этого используйте fmt.Print. Эта проверка, как правило, выдает результаты в существующем коде, поэтому применяется только тогда, когда версия языка (указанная директивой go.mod go или комментариями //go:build) не ниже Go 1.24, чтобы избежать сбоев непрерывной интеграции при обновлении до набора инструментов Go 1.24.

Существующий анализатор buildtag теперь выдает диагностику, когда в директиве //go:build есть недопустимое ограничение сборки основной версии Go. Например, //go:build go1.23.1 ссылается на точечный релиз; вместо этого используйте //go:build go1.23.

Существующий анализатор copylock теперь выдает диагностику, когда переменная, объявленная в цикле «for» из 3 предложений, например for i := iter(); done(i); i = next(i) { ... }, содержит sync.Locker, например sync.Mutex. Go 1.22 изменил поведение этих циклов, чтобы создавать новую переменную для каждой итерации, копируя значение из предыдущей итерации; эта операция копирования небезопасна для блокировок.

GOCACHEPROG

Внутренний двоичный и тестовый механизм кэширования cmd/go теперь может быть реализован дочерними процессами, реализующими протокол JSON между инструментом cmd/go и дочерним процессом, названным переменной среды GOCACHEPROG. Ранее это было за GOEXPERIMENT.

Runtime

Несколько улучшений производительности runtime снизили нагрузку на процессор в среднем на 2–3% по набору репрезентативных тестов. Результаты могут различаться в зависимости от приложения. Эти улучшения включают новую встроенную реализацию карты на основе Swiss Tables, более эффективное распределение памяти для небольших объектов и новую реализацию внутреннего мьютекса во время выполнения.

Новую встроенную реализацию карты и новый внутренний мьютекс во время выполнения можно отключить, установив GOEXPERIMENT=noswissmap и GOEXPERIMENT=nospinbitmutex во время сборки соответственно.

Компилятор

Компилятор уже запрещал определять новые методы с типами приемников, которые были сгенерированы cgo, но это ограничение можно было обойти с помощью типа псевдонима. Go 1.24 теперь всегда сообщает об ошибке, если приемник обозначает тип, сгенерированный cgo, как напрямую, так и косвенно (через тип псевдонима).

Компоновщик

Компоновщик теперь по умолчанию генерирует идентификатор сборки GNU (заметка ELF NT_GNU_BUILD_ID) на платформах ELF и UUID (команда загрузки Mach-O LC_UUID) на macOS. Идентификатор сборки или UUID выводится из идентификатора сборки Go. Его можно отключить с помощью флага компоновщика -B none или переопределить с помощью флага компоновщика -B 0xNNNN с указанным пользователем шестнадцатеричным значением.

Bootstrap

Как упоминалось в примечаниях к релизу Go 1.22, Go 1.24 теперь требует Go 1.22.6 или более поздней версии для bootstrap. Ожидается, что Go 1.26 потребует точечный релиз Go 1.24 или более поздней версии для bootstrap.

Стандартная библиотека

Ограниченный каталогом доступ к файловой системе

Новый тип os.Root обеспечивает возможность выполнять операции с файловой системой в определенном каталоге.

Функция os.OpenRoot открывает каталог и возвращает os.Root. Методы os.Root работают в каталоге и не допускают пути, ссылающиеся на местоположения за пределами каталога, включая те, которые следуют по символическим ссылкам из каталога. Методы os.Root отражают большинство операций с файловой системой, доступных в пакете os, включая, например, os.Root.Open, os.Root.Create, os.Root.Mkdir и os.Root.Stat.

Новая функция бенчмарка

Теперь бенчмарки могут использовать более быстрый и менее подверженный ошибкам метод testing.B.Loop для выполнения итераций бенчмарка, например for b.Loop() { ... } вместо типичных структур цикла, включающих b.N, например for range b.N. Это дает два существенных преимущества:

  • Функция бенчмарка будет выполняться ровно один раз за -count, поэтому дорогостоящие шаги настройки и очистки выполняются только один раз.
  • Параметры вызова функции и результаты сохраняются, что не позволяет компилятору полностью оптимизировать тело цикла.

Улучшенные финализаторы

Новая функция runtime.AddCleanup — это механизм финализации, который более гибкий, более эффективный и менее подвержен ошибкам, чем runtime.SetFinalizer. AddCleanup присоединяет функцию очистки к объекту, которая будет запущена, когда объект больше не будет доступен. Однако, в отличие от SetFinalizer, несколько очисток могут быть присоединены к одному объекту, очистки могут быть присоединены к внутренним указателям, очистки обычно не вызывают утечек, когда объекты образуют цикл, и очистки не задерживают освобождение объекта или объектов, на которые он указывает. Новый код должен предпочесть AddCleanup, а не SetFinalizer.

Новый пакет weak

Новый пакет weak предоставляет слабые указатели.

Слабые указатели — это примитив низкого уровня, предоставляемый для создания структур с эффективным использованием памяти, таких как слабые карты для связывания значений, карты канонизации для всего, что не охвачено package unique, и различные виды кэшей. Для поддержки этих вариантов использования этот релиз также предоставляет runtime.AddCleanup и maphash.Comparable.

Новый пакет crypto/mlkem

Новый пакет crypto/mlkem реализует ML-KEM-768 и ML-KEM-1024.

ML-KEM — это постквантовый механизм обмена ключами, ранее известный как Kyber и описанный в FIPS 203.

Новые пакеты crypto/hkdf, crypto/pbkdf2 и crypto/sha3

Новый пакет crypto/hkdf реализует функцию вывода ключа Extract-and-Expand на основе HMAC HKDF, как определено в RFC 5869.

Новый пакет crypto/pbkdf2 реализует функцию вывода ключа на основе пароля PBKDF2, как определено в RFC 8018.

Новый пакет crypto/sha3 реализует хэш-функцию SHA-3 и функции расширяемого вывода SHAKE и cSHAKE, как определено в FIPS 202.

Все три пакета основаны на уже существующих пакетах golang.org/x/crypto/....

Соответствие FIPS 140-3

Этот релиз включает новый набор механизмов для обеспечения соответствия FIPS 140-3.

Go Cryptographic Module — это набор внутренних стандартных пакетов библиотеки, которые прозрачно используются для реализации алгоритмов, одобренных FIPS 140-3. Приложения не требуют никаких изменений для использования Go Cryptographic Module для одобренных алгоритмов.

Новая переменная среды GOFIPS140 может использоваться для выбора версии Go Cryptographic Module для использования в сборке. Новая настройка fips140 GODEBUG может использоваться для включения режима FIPS 140-3 во время выполнения.

Go 1.24 включает Go Cryptographic Module версии v1.0.0, которая в настоящее время проходит тестирование в лаборатории, аккредитованной CMVP.

Новый экспериментальный пакет testing/synctest

Новый экспериментальный пакет testing/synctest обеспечивает поддержку тестирования параллельного кода.

Функция synctest.Run запускает группу горутин в изолированном «пузыре». Внутри пузыря функции пакета времени работают по поддельным часам.

Функция synctest.Wait ждет, пока все горутины в текущем пузыре заблокируются.

Пакет synctest является экспериментальным и должен быть включен путем установки GOEXPERIMENT=synctest во время сборки. API пакета может быть изменен в будущих релизах.

Минорные изменения в библиотеке

archive

Реализации (*Writer).AddFS в archive/zip и archive/tar теперь записывают заголовок каталога для пустого каталога.

bytes

Пакет bytes добавляет несколько функций, которые работают с итераторами:

  • Lines возвращает итератор по строкам, завершающимся символом новой строки, в байтовом срезе.
  • SplitSeq возвращает итератор по всем подсрезам байтового среза, разделенного вокруг разделителя.
  • SplitAfterSeq возвращает итератор по подсрезам байтового среза, разделенного после каждого экземпляра разделителя.
  • FieldsSeq возвращает итератор по подсрезам байтового среза, разделенного вокруг пробельных символов, как определено unicode.IsSpace.
  • FieldsFuncSeq возвращает итератор по подсрезам байтового среза, разделенного вокруг кодовых точек Unicode, удовлетворяющих предикату.

crypto/aes

Значение, возвращаемое NewCipher, больше не реализует методы NewCTR, NewGCM, NewCBCEncrypter и NewCBCDecrypter. Эти методы не были документированы и доступны не на всех архитектурах. Вместо этого значение Block должно передаваться непосредственно соответствующим функциям crypto/cipher. На данный момент crypto/cipher по-прежнему проверяет эти методы в значениях Block, даже если они больше не используются стандартной библиотекой.

crypto/cipher

Новая функция NewGCMWithRandomNonce возвращает AEAD, который реализует AES-GCM, генерируя случайный одноразовый код во время Seal и добавляя его к зашифрованному тексту.

Реализация Stream, возвращаемая NewCTR при использовании с crypto/aes, теперь в несколько раз быстрее на amd64 и arm64.

NewOFB, NewCFBEncrypter и NewCFBDecrypter теперь устарели. Режимы OFB и CFB не аутентифицированы, что обычно позволяет активным атакам манипулировать и восстанавливать открытый текст. Рекомендуется, чтобы приложения использовали режимы AEAD. Если требуется неаутентифицированный режим Stream, используйте NewCTR.

crypto/ecdsa

PrivateKey.Sign теперь создает детерминированную подпись в соответствии с RFC 6979, если случайный источник равен нулю.

crypto/md5

Значение, возвращаемое md5.New, теперь также реализует интерфейс encoding.BinaryAppender.

crypto/rand

Функция Read теперь гарантированно не даст сбой. Она всегда будет возвращать nil в качестве результата ошибки. Если Read столкнется с ошибкой при чтении из Reader, программа безвозвратно завершится сбоем. Обратите внимание, что API платформы, используемые Reader по умолчанию, задокументированы как всегда успешные, поэтому это изменение должно повлиять только на программы, которые переопределяют переменную Reader. Исключением являются ядра Linux до версии 3.17, где Reader по умолчанию все еще открывает /dev/urandom и может дать сбой.

В Linux 6.11 и более поздних версиях Reader теперь использует системный вызов getrandom через vDSO. Это в несколько раз быстрее, особенно для небольших чтений.

В OpenBSD Reader теперь использует arc4random_buf(3).

Новая функция Text может использоваться для генерации криптографически защищенных случайных текстовых строк.

crypto/rsa

GenerateKey теперь возвращает ошибку, если запрашивается ключ длиной менее 1024 бит. Все методы Sign, Verify, Encrypt и Decrypt теперь возвращают ошибку, если используются с ключом длиной менее 1024 бит. Такие ключи небезопасны и не должны использоваться. Настройка GODEBUG rsa1024min=0 восстанавливает старое поведение, но рекомендуется делать это только при необходимости и только в тестах, например, добавляя строку //go:debug rsa1024min=0 в тестовый файл. Новый пример GenerateKey предоставляет простой в использовании стандартный 2048-битный тестовый ключ.

Теперь безопасно и более эффективно вызывать PrivateKey.Precompute перед PrivateKey.Validate. Precompute теперь быстрее при наличии частично заполненных PrecomputedValues, например, при демаршалировании ключа из JSON.

Пакет теперь отклоняет больше недействительных ключей, даже если Validate не вызывается, а GenerateKey может возвращать новые ошибки для сломанных случайных источников. Поля Primes и Precomputed PrivateKey теперь используются и проверяются, даже если некоторые значения отсутствуют.

SignPKCS1v15 и VerifyPKCS1v15 теперь поддерживают SHA-512/224, SHA-512/256 и SHA-3.

GenerateKey теперь использует немного другой метод для генерации закрытой экспоненты (тотиент Кармайкла вместо тотиента Эйлера). Редкие приложения, которые внешне регенерируют ключи только из простых множителей, могут давать разные, но совместимые результаты.

Операции с открытыми и закрытыми ключами теперь выполняются в два раза быстрее на wasm.

crypto/sha1

Значение, возвращаемое sha1.New, теперь также реализует интерфейс encoding.BinaryAppender.

crypto/sha256

Значения, возвращаемые sha256.New и sha256.New224, теперь также реализуют интерфейс encoding.BinaryAppender.

crypto/sha512

Значения, возвращаемые sha512.New, sha512.New384, sha512.New512_224 и sha512.New512_256, теперь также реализуют интерфейс encoding.BinaryAppender.

crypto/subtle

Новая функция WithDataIndependentTiming позволяет пользователю запускать функцию с включенными функциями, специфичными для архитектуры, которые гарантируют, что определенные инструкции являются инвариантными по времени значениями данных. Это можно использовать для того, чтобы убедиться, что код, разработанный для выполнения в постоянном времени, не оптимизирован функциями уровня ЦП, так что он работает в переменном времени. В настоящее время WithDataIndependentTiming использует бит PSTATE.DIT на arm64 и является пустой операцией на всех других архитектурах. GODEBUG настройка dataindependenttiming=1 включает режим DIT для всей программы Go.

Выход XORBytes должен точно перекрываться или не перекрываться входами. Раньше поведение было неопределенным, а теперь XORBytes паникует.

crypto/tls

Сервер TLS теперь поддерживает Encrypted Client Hello (ECH). Эту функцию можно включить, заполнив поле Config.EncryptedClientHelloKeys.

Новый механизм обмена ключами X25519MLKEM768 после квантового режима теперь поддерживается и включается по умолчанию, когда Config.CurvePreferences равен нулю. Параметр GODEBUG tlsmlkem=0 отменяет значение по умолчанию. Это может быть полезно при работе с неисправными серверами TLS, которые некорректно обрабатывают большие записи, вызывая тайм-аут во время рукопожатия.

Поддержка экспериментального обмена ключами X25519Kyber768Draft00 была удалена.

Порядок обмена ключами теперь полностью обрабатывается пакетом crypto/tls. Порядок Config.CurvePreferences теперь игнорируется, а содержимое используется только для определения того, какие обмены ключами следует включить при заполнении поля.

Новое поле ClientHelloInfo.Extensions содержит идентификаторы расширений, полученных в сообщении Client Hello. Это может быть полезно для идентификации клиентов TLS.

crypto/x509

Настройка x509sha1 GODEBUG была удалена. Certificate.Verify больше не поддерживает подписи на основе SHA-1.

OID теперь реализует интерфейсы encoding.BinaryAppender и encoding.TextAppender.

Поле политик сертификатов по умолчанию изменилось с Certificate.PolicyIdentifiers на Certificate.Policies. При анализе сертификатов будут заполнены оба поля, но при создании сертификатов политики теперь будут взяты из поля Certificate.Policies вместо поля Certificate.PolicyIdentifiers. Это изменение можно отменить с помощью настройки GODEBUG x509usepolicies=0.

CreateCertificate теперь будет генерировать серийный номер с использованием метода, соответствующего RFC 5280, при передаче шаблона с нулевым полем Certificate.SerialNumber вместо сбоя.

Certificate.Verify теперь поддерживает проверку политики, как определено в RFC 5280 и RFC 9618. Новое поле VerifyOptions.CertificatePolicies может быть установлено на приемлемый набор OID политики. Из Certificate.Verify будут возвращены только цепочки сертификатов с допустимыми графами политики.

MarshalPKCS8PrivateKey теперь возвращает ошибку вместо маршалинга недействительного ключа RSA. (MarshalPKCS1PrivateKey не возвращает ошибку, и его поведение при предоставлении недействительных ключей по-прежнему не определено.)

ParsePKCS1PrivateKey и ParsePKCS8PrivateKey теперь используют и проверяют закодированные значения CRT, поэтому могут отклонять недействительные ключи RSA, которые были приняты ранее. Используйте настройку GODEBUG x509rsacrt=0, чтобы вернуться к пересчету значений CRT.

debug/elf

Пакет debug/elf добавляет поддержку обработки версий символов в динамических файлах ELF (исполняемый и связываемый формат). Новый метод File.DynamicVersions возвращает список динамических версий, определенных в файле ELF. Новый метод File.DynamicVersionNeeds возвращает список динамических версий, требуемых этим файлом ELF, которые определены в других объектах ELF. Наконец, новые поля Symbol.HasVersion и Symbol.VersionIndex указывают версию символа.

encoding

Два новых интерфейса, TextAppender и BinaryAppender, были введены для добавления текстового или двоичного представления объекта к байтовому срезу. Эти интерфейсы предоставляют ту же функциональность, что и TextMarshaler и BinaryMarshaler, но вместо того, чтобы каждый раз выделять новый срез, они добавляют данные непосредственно к существующему срезу. Эти интерфейсы теперь реализуются стандартными библиотечными типами, которые уже реализовали TextMarshaler и/или BinaryMarshaler.

encoding/json

При маршалинге поле структуры с новой опцией omitzero в теге поля структуры будет опущено, если его значение равно нулю. Если тип поля имеет метод IsZero() bool, он будет использоваться для определения, равно ли значение нулю. В противном случае значение равно нулю, если это нулевое значение для его типа. Тег поля omitzero более понятен и менее подвержен ошибкам, чем omitempty, когда намерение состоит в том, чтобы опустить нулевые значения. В частности, в отличие от omitempty, omitzero опускает нулевые значения time.Time, что является распространенным источником проблем.

Если указаны и omitempty, и omitzero, поле будет опущено, если значение либо пустое, либо нулевое (или оба).

UnmarshalTypeError.Field теперь включает встроенные структуры для предоставления более подробных сообщений об ошибках.

go/types

Все структуры данных go/types, которые предоставляют последовательности с помощью пары методов, таких как Len() int и At(int) T, теперь также имеют методы, которые возвращают итераторы, что позволяет упростить код, например:

params := fn.Type.(*types.Signature).Params()
for i := 0; i < params.Len(); i++ {
    use(params.At(i))
}

к виду:

for param := range fn.Signature().Params().Variables() {
    use(param)
}

Добавлены методы: Interface.EmbeddedTypes, Interface.ExplicitMethods, Interface.Methods, MethodSet.Methods, Named.Methods, Scope.Children, Struct.Fields, Tuple.Variables, TypeList.Types, TypeParamList.TypeParams, Union.Terms.

hash/adler32

Значение, возвращаемое New, теперь также реализует интерфейс encoding.BinaryAppender.

hash/crc32

Значения, возвращаемые New и NewIEEE, теперь также реализуют интерфейс encoding.BinaryAppender.

hash/crc64

Значение, возвращаемое New, теперь также реализует интерфейс encoding.BinaryAppender.

hash/fnv

Значения, возвращаемые New32, New32a, New64, New64a, New128 и New128a, теперь также реализуют интерфейс encoding.BinaryAppender.

hash/maphash

Новые функции Comparable и WriteComparable могут вычислять хеш любого сопоставимого значения. Они позволяют хешировать все, что может использоваться в качестве ключа карты Go.

log/slog

Новый DiscardHandler — это обработчик, который никогда не включается и всегда отбрасывает свой вывод.

Level и LevelVar теперь реализуют интерфейс encoding.TextAppender.

math/big

Float, Int и Rat теперь реализуют интерфейс encoding.TextAppender.

math/rand

Вызовы устаревшей функции Seed верхнего уровня больше не имеют никакого эффекта. Чтобы восстановить старое поведение, используйте настройку GODEBUG randseednop=0.

math/rand/v2

ChaCha8 и PCG теперь реализуют интерфейс encoding.BinaryAppender.

net

ListenConfig теперь использует MPTCP по умолчанию в системах, где он поддерживается (в настоящее время только в Linux).

IP теперь реализует интерфейс encoding.TextAppender.

net/http

Ограничение Transport на информационные ответы 1xx, полученные в ответ на запрос, изменилось. Ранее он прерывал запрос и возвращал ошибку после получения более 5 ответов 1xx. Теперь он возвращает ошибку, если общий размер всех ответов 1xx превышает настройку конфигурации Transport.MaxResponseHeaderBytes.

Кроме того, когда запрос имеет хук трассировки net/http/httptrace.ClientTrace.Got1xxResponse, теперь нет ограничений на общее количество ответов 1xx. Хук Got1xxResponse может вернуть ошибку, чтобы прервать запрос.

Transport и Server теперь имеют поле HTTP2, которое позволяет настраивать параметры протокола HTTP/2.

Новые поля Server.Protocols и Transport.Protocols предоставляют простой способ настройки протоколов HTTP, используемых сервером или клиентом.

Сервер и клиент могут быть настроены для поддержки незашифрованных соединений HTTP/2.

Когда Server.Protocols содержит UnencryptedHTTP2, сервер будет принимать соединения HTTP/2 на незашифрованных портах. Сервер может принимать как HTTP/1, так и незашифрованный HTTP/2 на одном и том же порту.

Если Transport.Protocols содержит UnencryptedHTTP2 и не содержит HTTP1, транспорт будет использовать незашифрованный HTTP/2 для http:// URL-адресов. Если транспорт настроен на использование как HTTP/1, так и незашифрованного HTTP/2, он будет использовать HTTP/1.

Поддержка незашифрованного HTTP/2 использует «HTTP/2 с предшествующими знаниями» (RFC 9113, раздел 3.3). Устаревший заголовок «Upgrade: h2c» не поддерживается.

net/netip

Addr, AddrPort и Prefix теперь реализуют интерфейсы encoding.BinaryAppender и encoding.TextAppender.

net/url

URL теперь также реализует интерфейс encoding.BinaryAppender.

os/user

В Windows Current теперь можно использовать в Windows Nano Server. Реализация была обновлена, чтобы избежать использования функций из библиотеки NetApi32, которая недоступна в Nano Server.

В Windows Current, Lookup и LookupId теперь поддерживают следующие встроенные учетные записи пользователей служб:

  • NT AUTHORITY\SYSTEM
  • NT AUTHORITY\LOCAL SERVICE
  • NT AUTHORITY\NETWORK SERVICE

В Windows Current стал значительно быстрее, когда текущий пользователь присоединен к медленному домену, что является обычным случаем для многих корпоративных пользователей. Производительность новой реализации теперь составляет порядка миллисекунд по сравнению с предыдущей реализацией, которая могла занять несколько секунд или даже минут.

В Windows Current теперь возвращает пользователя-владельца процесса, когда текущий поток выдает себя за другого пользователя. Ранее он возвращал ошибку.

regexp

Теперь Regexp реализует интерфейс encoding.TextAppender.

runtime

Функция GOROOT теперь устарела. В новом коде предпочтительнее использовать системный путь для поиска двоичного файла «go» и использовать go env GOROOT для поиска его GOROOT.

strings

Пакет strings добавляет несколько функций, которые работают с итераторами:

  • Lines возвращает итератор по строкам, завершающимся символом новой строки, в строке.
  • SplitSeq возвращает итератор по всем подстрокам строки, разделенной по разделителю.
  • SplitAfterSeq возвращает итератор по подстрокам строки, разделенной после каждого экземпляра разделителя.
  • FieldsSeq возвращает итератор по подстрокам строки, разделенной по пробельным символам, как определено в unicode.IsSpace.
  • FieldsFuncSeq возвращает итератор по подстрокам строки, разделенной вокруг последовательностей кодовых точек Unicode, удовлетворяющих предикату.

sync

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

Если у вас возникнут какие-либо проблемы, установите GOEXPERIMENT=nosynchashtriemap во время сборки, чтобы вернуться к старой реализации, и сообщите о проблеме.

testing

Новые методы T.Context и B.Context возвращают контекст, который отменяется после завершения теста и до запуска функций очистки теста.

Новые методы T.Chdir и B.Chdir можно использовать для изменения рабочего каталога на время теста или бенчмарка.

text/template

Теперь шаблоны поддерживают range-over-func и range-over-int.

time

Теперь Time реализует интерфейсы encoding.BinaryAppender и encoding.TextAppender.

Порты

Linux

Как было объявлено в примечаниях к релизу Go 1.23, для Go 1.24 требуется ядро Linux версии 3.2 или более поздней.

Darwin

Go 1.24 — последний релиз, который будет работать на macOS 11 Big Sur. Для Go 1.25 потребуется macOS 12 Monterey или более поздней версии.

WebAssembly

Директива компилятора go:wasmexport добавлена для программ Go для экспорта функций на хост WebAssembly.

В WebAssembly System Interface Preview 1 (GOOS=wasip1 GOARCH=wasm) Go 1.24 поддерживает сборку программы Go в качестве реактора/библиотеки, указав флаг сборки -buildmode=c-shared.

Теперь больше типов разрешено в качестве типов аргументов или результатов для функций go:wasmimport. В частности, разрешены bool, string, uintptr и указатели на определенные типы, а также 32- и 64-битные целые и float типы и unsafe.Pointer, которые уже разрешены. Эти типы также разрешены в качестве типов аргументов или результатов для функций go:wasmexport.

Файлы поддержки для WebAssembly были перемещены в lib/wasm из misc/wasm.

Начальный размер памяти значительно уменьшен, особенно для небольших приложений WebAssembly.

Windows

32-битный порт windows/arm (GOOS=windows GOARCH=arm) отмечен как сломанный.


Читайте также:


купить игрушку gopher

пятница, 18 октября 2024 г.

Как итерировать по символам в строках Go

В Go итерация по строке по ее символам (или знакам) может быть выполнена несколькими различными способами.

Использование цикла for...range

Наиболее распространенный и идиоматический способ итерации по строке в Go — использование цикла for...range. Этот метод правильно обрабатывает символы Unicode, рассматривая каждый символ как руну (что является псевдонимом для int32). Вот пример:

package main

import "fmt"

func main() {
    str := "Hello, 世界" // Строка с символами ASCII и не-ASCII

    for index, char := range str {
        fmt.Printf("Index: %d, Character: %c\n", index, char)
    }
}

Вывод:

Index: 0, Character: H
Index: 1, Character: e
Index: 2, Character: l
Index: 3, Character: l
Index: 4, Character: o
Index: 5, Character: ,
Index: 6, Character:
Index: 7, Character: 世
Index: 8, Character: 界

Использование стандартного цикла for с рунами

Если вы предпочитаете использовать традиционный цикл for, вы можете преобразовать строку в срез рун. Это позволяет вам перебирать каждый символ, сохраняя правильное представление символов Unicode:

package main

import "fmt"

func main() {
    str := "Hello, 世界"
    runes := []rune(str) // Преобразовать строку в срез рун

    for i := 0; i < len(runes); i++ {
        fmt.Printf("Rune %d is '%c'\n", i, runes[i])
    }
}

Вывод:

Rune 0 is 'H'
Rune 1 is 'e'
Rune 2 is 'l'
Rune 3 is 'l'
Rune 4 is 'o'
Rune 5 is ','
Rune 6 is ' '
Rune 7 is '世'
Rune 8 is '界'

Использование метода strings.Split

Другой подход — использовать метод strings.Split для разделения строки на отдельные символы. Однако этот метод может быть не таким эффективным или идиоматичным, как предыдущие методы:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello, 世界"
    chars := strings.Split(str, "") // Разделить строку на отдельные символы

    for _, char := range chars {
        fmt.Printf("Character: %s\n", char)
    }
}

Вывод:

Character: H
Character: e
Character: l
Character: l
Character: o
Character: ,
Character:
Character: 世
Character: 界

В Go предпочтительным способом перебора строк по символам является использование цикла for...range, поскольку он автоматически обрабатывает кодировку UTF-8 и обеспечивает простой способ доступа к каждому символу как к руне. В качестве альтернативы преобразование строки в срез рун обеспечивает больший контроль с помощью традиционной индексации. Метод strings.Split также можно использовать, но он менее эффективен для этой цели. Понимание этих методов поможет вам эффективно работать со строками в Go.


Читайте также:


Строки как тип данных в Go

В Go (Golang) строка — это фундаментальный тип данных, используемый для представления последовательности символов. Он широко используется для обработки текста и необходим для различных задач программирования.

Характеристики строк в Go

Неизменяемость - после создания строки ее значение не может быть изменено. Любая операция, которая, как кажется, изменяет строку, на самом деле создает новую строку. Эта неизменяемость помогает оптимизировать использование памяти и обеспечить безопасность потоков.

Кодировка UTF-8 - строки в Go по умолчанию кодируются в UTF-8, что позволяет им представлять широкий спектр символов из разных языков. Каждый символ может занимать один или несколько байтов, что делает его гибким для интернационализации.

Срез байтов только для чтения - строку можно рассматривать как срез байтов только для чтения. Это означает, что хотя вы можете получить доступ к байтам, составляющим строку, вы не можете изменять их напрямую.

Создание строк

Строки в Go можно создавать с помощью двойных кавычек для интерпретируемых литералов или обратных кавычек для необработанных литералов.

Интерпретируемые литералы - поддерживают escape-последовательности (например, "\n" для новой строки).

str1 := "Hello, World!"

Необработанные литералы - заключены в обратные кавычки, они не поддерживают escape-последовательности и могут охватывать несколько строк.

str2 := `Это необработанный строковый литерал,
который может охватывать несколько строк.`

Операции и функции со строками

Go предоставляет несколько встроенных функций и методов для работы со строками, в основном через пакет strings. Некоторые распространенные операции включают:

Длина - используйте len() для получения количества байтов в строке.

length := len(str1) // Возвращает длину str1

Конкатенация - строки можно объединять с помощью оператора +.

combined := str1 + " " + str2

Подстрока - можно извлекать подстроки с помощью синтаксиса среза.

sub := str1[0:5] // "Hello"

Поиск и замена - функции, такие как strings.Contains(), strings.Replace() и strings.Index(), помогают находить подстроки или заменять части строк.

Пример кода

Вот простой пример, демонстрирующий создание строки и некоторые базовые операции:

package main

import (
    "fmt"
    "strings"
)

func main() {
    // Создание строк
    greeting := "Hello"
    name := "World"

    // Объединение строк
    message := greeting + ", " + name + "!"
    fmt.Println(message) // Вывод: Hello, World!

    // Проверка длины
    fmt.Println("Длина:", len(message)) // Вывод: Длина: 13

    // Поиск подстроки
    index := strings.Index(message, "World")
    fmt.Println("Индекс 'World':", index) // Вывод: Индекс 'World': 7

    // Замена подстроки
    newMessage := strings.Replace(message, "World", "Gopher", 1)
    fmt.Println(newMessage) // Вывод: Hello, Gopher!
}

Строки в Go — мощный, но простой в использовании инструмент, предоставляющий основные функции для обработки текста, обеспечивая при этом эффективность за счет неизменяемости и кодировки UTF-8. Понимание того, как эффективно работать со строками, имеет решающее значение для любого разработчика Go, поскольку они составляют основу большинства приложений, работающих с текстовыми данными.


Читайте также: