пятница, 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

Комментариев нет:

Отправить комментарий