среда, 28 августа 2024 г.

Релиз Go 1.23

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

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

Go 1.23 делает эксперимент (Go 1.22) "range-over-func" частью языка. "range" в цикле "for-range" теперь принимает функции итератора следующих типов

func(func() bool)
func(func(K) bool)
func(func(K, V) bool)

как выражения диапазона. Вызовы функции аргумента итератора создают значения итерации для цикла "for-range".

Go 1.23 включает предварительную поддержку псевдонимов универсальных типов. Создание цепочки инструментов с GOEXPERIMENT=aliastypeparams включает эту функцию в пакете. (Использование универсальных псевдонимов за пределами границ пакета пока не поддерживается.)

Инструменты

Телеметрия

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

Телеметрия Go — это включаемая по настройке система, управляемая командой go telemetry. По умолчанию программы цепочки инструментов собирают статистику в файлах счетчиков, которые можно проверять локально, но в остальном не используются (локальная телеметрия go).

Чтобы помочь разработчикам языка поддерживать хорошую работу Go и понимать использование Go рассмотрите возможность включения телеметрии Go, запустив go telemetry on. В этом режиме анонимные отчеты счетчиков еженедельно загружаются на telemetry.go.dev, где они объединяются в графики и также становятся доступными для загрузки любыми участниками Go или пользователями, желающими проанализировать данные.

Команда Go

Установка переменной среды GOROOT_FINAL больше не имеет эффекта. Дистрибутивы, которые устанавливают команду go в местоположение, отличное от $GOROOT/bin/go, должны устанавливать символическую ссылку вместо перемещения или копирования двоичного файла go.

Новый флаг go env -changed заставляет команду печатать только те настройки, эффективное значение которых отличается от значения по умолчанию, которое было бы получено в пустой среде без предварительного использования флага -w.

Новый флаг go mod tidy -diff заставляет команду не изменять файлы, а вместо этого печатать необходимые изменения в виде единого diff. Он завершается с ненулевым кодом, если требуются обновления.

Команда go list -m -json теперь включает новые поля Sum и GoModSum. Это похоже на существующее поведение команды go mod download -json.

Новая директива godebug в go.mod и go.work объявляет настройку GODEBUG для применения к используемому рабочему модулю или рабочему пространству.

Vet

Подкоманда go vet теперь включает анализатор stdversion, который помечает ссылки на символы, которые слишком новые для версии Go, действующей в ссылающемся файле. (Эффективная версия определяется директивой go в файле go.mod, включающем файл, и любыми ограничениями //go:build в файле.)

Например, она выдаст диагностику для ссылки на функцию reflect.TypeFor (введенную в go1.22) из ​​файла в модуле, файл go.mod которого указывает go 1.21.

Cgo

cmd/cgo поддерживает новый флаг -ldflags для передачи флагов компоновщику C. Команда go использует его автоматически, избегая ошибок “argument list too long” ("слишком длинный список аргументов") с очень большим CGO_LDFLAGS.

Trace

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

Среда выполнения

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

Компилятор

Накладные расходы на сборку с Profile Guided Optimization были значительно сокращены. Ранее большие сборки могли увидеть увеличение времени сборки на 100%+ при включении PGO. В Go 1.23 накладные расходы должны быть в однозначных процентах.

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

Для 386 и amd64 компилятор будет использовать информацию из PGO для выравнивания определенных горячих блоков в циклах. Это повышает производительность еще на 1-1,5% за счет дополнительных 0,1% размера текста и двоичного кода. В настоящее время это реализовано только на 386 и amd64, поскольку не показало улучшения на других платформах. Выравнивание горячих блоков можно отключить с помощью -gcflags=[<packages>=]-d=alignhot=0.

Компоновщик

Теперь компоновщик запрещает использовать директиву //go:linkname для ссылки на внутренние символы в стандартной библиотеке (включая среду выполнения), которые не отмечены //go:linkname в своих определениях. Аналогично компоновщик запрещает ссылки на такие символы из ассемблерного кода. Для обратной совместимости существующие использования //go:linkname, найденные в большом количестве открытого исходного кода, остаются поддерживаемыми. Любые новые ссылки на внутренние символы стандартной библиотеки будут запрещены.

Флаг командной строки компоновщика -checklinkname=0 можно использовать для отключения этой проверки в целях отладки и экспериментирования.

При сборке динамически связанного двоичного файла ELF (включая двоичный файл PIE) новый флаг -bindnow включает немедленное связывание функций.

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

Изменения таймера

Go 1.23 вносит два существенных изменения в реализацию time.Timer и time.Ticker.

Во-первых, таймеры и тикеры, на которые больше не ссылается программа, немедленно становятся доступными для сборки мусора, даже если их методы Stop не были вызваны. Более ранние версии Go не собирали неостановленные таймеры до тех пор, пока они не сработают, и никогда не собирали неостановленные тикеры.

Во-вторых, канал таймера, связанный с таймером или тикером, теперь не буферизован, с емкостью 0. Основной эффект этого изменения заключается в том, что Go теперь гарантирует, что для любого вызова метода Reset или Stop никакие устаревшие значения, подготовленные до этого вызова, не будут отправлены или получены после вызова. Более ранние версии Go использовали каналы с одноэлементным буфером, что затрудняло правильное использование Reset и Stop. Видимым эффектом этого изменения является то, что len и cap каналов таймера теперь возвращают 0 вместо 1, что может повлиять на программы, которые опрашивают длину, чтобы решить, будет ли прием на канале таймера успешным. Такой код должен использовать неблокируемый прием вместо этого.

Эти новые поведения включаются только тогда, когда основная программа Go находится в модуле со строкой go в go.mod, использующей Go 1.23.0 или более позднюю версию. Когда Go 1.23 собирает старые программы, старые поведения остаются в силе. Новая настройка GODEBUG asynctimerchan=1 может использоваться для возврата к асинхронному поведению канала, даже если программа называет Go 1.23.0 или более позднюю версию в своем файле go.mod.

Новый пакет unique

Новый пакет unique предоставляет возможности для канонизации значений (например, "интернирование" или "хэш-консинг").

Любое значение сопоставимого типа может быть канонизировано с помощью новой функции Make[T], которая создает ссылку на каноническую копию значения в форме Handle[T]. Два Handle[T] равны тогда и только тогда, когда значения, используемые для создания дескрипторов, равны, что позволяет программам дедуплицировать значения и уменьшать свой объем памяти. Сравнение двух значений Handle[T] эффективно, сводясь к простому сравнению указателей.

Итераторы

Новый пакет iter предоставляет основные определения для работы с пользовательскими итераторами.

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

  • All возвращает итератор по индексам и значениям среза.
  • Values возвращает итератор по элементам среза.
  • Backward возвращает итератор, который проходит по срезу в обратном направлении.
  • Collect собирает значения из итератора в новый срез.
  • AppendSeq добавляет значения из итератора в существующий срез.
  • Sorted собирает значения из итератора в новый срез, а затем сортирует срез.
  • SortedFunc похож на Sorted, но с функцией сравнения.
  • SortedStableFunc похож на SortFunc, но использует стабильный алгоритм сортировки.
  • Chunk возвращает итератор по последовательным подсрезам до n элементов среза.

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

  • All возвращает итератор по парам ключ-значение из карты.
  • Keys возвращает итератор по ключам в карте.
  • Values возвращает итератор по значениям в карте.
  • Insert добавляет пары ключ-значение из итератора в существующую карту.
  • Collect собирает пары ключ-значение из итератора в новую карту и возвращает ее.

Новый пакет structs

Новый пакет structs предоставляет типы для полей структур, которые изменяют свойства содержащего типа структуры, такие как макет памяти.

В этом релизе единственным таким типом является HostLayout, который указывает, что структура с полем этого типа имеет макет, который соответствует ожиданиям платформы хоста. HostLayout следует использовать в типах, которые передаются, возвращаются или доступны через указатель, переданный в/из API хоста. Без этого маркера порядок макета структур не гарантируется спецификацией языка, хотя с версии Go 1.23 макеты хоста и языка совпадают.

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

archive/tar

Если аргумент FileInfoHeader реализует новый интерфейс FileInfoNames, то методы интерфейса будут использоваться для установки Uname/Gname заголовка файла. Это позволяет приложениям переопределять зависящий от системы поиск Uname/Gname.

crypto/tls

Клиент TLS теперь поддерживает черновую спецификацию Encrypted Client Hello. Эту функцию можно включить, установив поле Config.EncryptedClientHelloConfigList в закодированный ECHConfigList для хоста, к которому выполняется подключение.

Тип QUICConn, используемый реализациями QUIC, включает новые события, сообщающие о состоянии возобновления сеанса, и предоставляет способ для уровня QUIC добавлять данные в билеты сеанса и записи кэша сеанса.

Наборы шифров 3DES были удалены из списка по умолчанию, используемого, когда Config.CipherSuites равен нулю. Значение по умолчанию можно вернуть, добавив tls3des=1 в переменную среды GODEBUG.

Экспериментальный постквантовый механизм обмена ключами X25519Kyber768Draft00 теперь включен по умолчанию, когда Config.CurvePreferences равен нулю. Значение по умолчанию можно вернуть, добавив tlskyber=0 в переменную среды GODEBUG.

В версии 1.23 поведение X509KeyPair и LoadX509KeyPair изменено для заполнения поля Certificate.Leaf возвращаемого сертификата. Для этого поведения добавлен новый параметр x509keypairleaf GODEBUG.

crypto/x509

CreateCertificateRequest теперь правильно поддерживает алгоритмы подписи RSA-PSS.

CreateCertificateRequest и CreateRevocationList теперь проверяют сгенерированную подпись с помощью открытого ключа подписчика. Если подпись недействительна, возвращается ошибка. Это поведение CreateCertificate с версии Go 1.16.

Параметр x509sha1 GODEBUG будет удален в следующем основном релизе Go (Go 1.24). Это будет означать, что crypto/x509 больше не будет поддерживать проверку подписей на сертификатах, использующих алгоритмы подписи на основе SHA-1.

Новая функция ParseOID анализирует строку идентификатора объекта ASN.1, закодированную точками. Тип OID теперь реализует интерфейсы encoding.BinaryMarshaler, encoding.BinaryUnmarshaler, encoding.TextMarshaler, encoding.TextUnmarshaler.

database/sql

Ошибки, возвращаемые реализациями driver.Valuer, теперь заключены в оболочку для улучшенной обработки ошибок во время таких операций, как DB.Query, DB.Exec и DB.QueryRow.

debug/elf

Пакет debug/elf теперь определяет PT_OPENBSD_NOBTCFI. Этот ProgType используется для отключения принудительного применения Branch Tracking Control Flow Integrity (BTCFI) в двоичных файлах OpenBSD.

Теперь определяет константы типа символа STT_RELC, STT_SRELC и STT_GNU_IFUNC.

coding/binary

Новые функции Encode и Decode являются эквивалентами байтовых срезов Read и Write. Append позволяет объединять несколько данных в один байтовый срез.

go/ast

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

go/types

Тип Func, представляющий символ функции или метода, теперь имеет метод Func.Signature, который возвращает тип функции, который всегда является Signature.

Тип Alias теперь имеет метод Rhs, который возвращает тип в правой части его объявления: учитывая тип A = B, Rhs A равен B.

Были добавлены методы Alias.Origin, Alias.SetTypeParams, Alias.TypeParams и Alias.TypeArgs. Они необходимы для типов-псевдонимов.

По умолчанию go/types теперь создает узлы типа Alias ​​для псевдонимов типов. Это поведение можно контролировать с помощью флага GODEBUG gotypesalias. Его значение по умолчанию изменилось с 0 в Go 1.22 на 1 в Go 1.23.

math/rand/v2

Были добавлены функция Uint и метод Rand.Uint. Они были непреднамеренно исключены из Go 1.22.

Новый метод ChaCha8.Read реализует интерфейс io.Reader.

net

Новый тип KeepAliveConfig позволяет настраивать параметры поддержки активности для TCP-соединений с помощью нового метода TCPConn.SetKeepAliveConfig и новых полей KeepAliveConfig для Dialer и ListenConfig.

Тип DNSError теперь оборачивает ошибки, вызванные тайм-аутами или отменой. Например, error.Is(someDNSErr, context.DeadlineExceedeed) теперь будет сообщать, была ли ошибка DNS вызвана тайм-аутом.

Новый параметр GODEBUG netedns0=0 отключает отправку дополнительных заголовков EDNS0 в запросах DNS, поскольку, как сообщается, они нарушают работу DNS-сервера на некоторых модемах.

net/http

Cookie теперь сохраняет двойные кавычки вокруг значения cookie. Новое поле Cookie.Quoted указывает, было ли Cookie.Value изначально закавычено.

Новый метод Request.CookiesNamed извлекает все cookie, соответствующие заданному имени.

Новое поле Cookie.Partitioned идентифицирует файлы cookie с атрибутом Partitioned.

Шаблоны, используемые ServeMux, теперь допускают один или несколько пробелов или табуляций после имени метода. Ранее разрешался только один пробел.

Новая функция ParseCookie анализирует значение заголовка Cookie и возвращает все файлы cookie, которые были установлены в нем. Поскольку одно и то же имя файла cookie может встречаться несколько раз, возвращаемые значения могут содержать более одного значения для данного ключа.

Новая функция ParseSetCookie анализирует значение заголовка Set-Cookie и возвращает файл cookie. Она возвращает ошибку при синтаксической ошибке.

ServeContent, ServeFile и ServeFileFS теперь удаляют заголовки Cache-Control, Content-Encoding, Etag и Last-Modified при обслуживании ошибки. Эти заголовки обычно применяются к содержимому без ошибок, но не к тексту ошибок.

Промежуточное ПО, которое оборачивает ResponseWriter и применяет кодирование "на лету", например Content-Encoding: gzip, не будет работать после этого изменения. Предыдущее поведение ServeContent, ServeFile и ServeFileFS можно восстановить, установив GODEBUG=httpservecontentkeepheaders=1.

Обратите внимание, что промежуточное ПО, которое изменяет размер обслуживаемого контента (например, сжимая его), уже не работает должным образом, когда ServeContent обрабатывает запрос Range. Сжатие "на лету" должно использовать заголовок Transfer-Encoding вместо Content-Encoding.

Для входящих запросов новое поле Request.Pattern содержит шаблон ServeMux (если есть), который соответствует запросу. Это поле не задается, если задано GODEBUG=httpmuxgo121=1.

net/http/httptest

Новый метод NewRequestWithContext создает входящий запрос с context.Context.

net/netip

В Go 1.22 и более ранних версиях использование reflect.DeepEqual для сравнения Addr, содержащего адрес IPv4, с Addr, содержащим форму IPv6, сопоставленную с IPv4, неправильно возвращало значение true, даже если значения Addr отличались при сравнении с == или Addr.Compare. Теперь эта ошибка исправлена, и все три подхода теперь выдают одинаковый результат.

os

Функция Stat теперь устанавливает бит ModeSocket для файлов, которые являются сокетами Unix в Windows. Эти файлы идентифицируются по тегу повторной обработки, установленному на IO_REPARSE_TAG_AF_UNIX.

В Windows биты режима, сообщаемые Lstat и Stat для точек повторной обработки, изменились. Точки монтирования больше не имеют установленного ModeSymlink, а точки повторной обработки, которые не являются символическими ссылками, сокетами Unix или файлами дедупликации, теперь всегда имеют установленный ModeIrregular. Это поведение контролируется настройкой winsymlink. Для Go 1.23 по умолчанию установлено значение winsymlink=1. Для предыдущих версий по умолчанию установлено значение winsymlink=0.

Функция CopyFS копирует io/fs.FS в локальную файловую систему.

В Windows Readlink больше не пытается нормализовать тома по буквам дисков, что не всегда было возможно. Такое поведение контролируется настройкой winreadlinkvolume. Для Go 1.23 по умолчанию установлено значение winreadlinkvolume=1. Для предыдущих версий по умолчанию установлено значение winreadlinkvolume=0.

В Linux с поддержкой pidfd (обычно Linux v5.4+) функции и методы, связанные с процессами, используют pidfd (а не PID) внутренне, что исключает потенциальное неправильное нацеливание при повторном использовании PID ОС. Поддержка Pidfd полностью прозрачна для пользователя, за исключением дополнительных дескрипторов файлов процессов, которые могут быть у процесса.

path/filepath

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

В Windows EvalSymlinks больше не оценивает точки монтирования, что было источником многих несоответствий и ошибок. Это поведение контролируется настройкой winsymlink. Для Go 1.23 по умолчанию установлено winsymlink=1. В предыдущих версиях по умолчанию установлено winsymlink=0.

В Windows EvalSymlinks больше не пытается нормализовать тома по буквам дисков, что не всегда было возможно. Это поведение контролируется настройкой winreadlinkvolume. Для Go 1.23 по умолчанию установлено winreadlinkvolume=1. В предыдущих версиях по умолчанию установлено winreadlinkvolume=0.

reflect

В Type добавлены новые методы, синонимичные методам с тем же именем в Value:

  • Type.OverflowComplex
  • Type.OverflowFloat
  • Type.OverflowInt
  • Type.OverflowUint

Новая функция SliceAt аналогична NewAt, но для срезов.

Методы Value.Pointer и Value.UnsafePointer теперь поддерживают значения типа String.

Новые методы Value.Seq и Value.Seq2 возвращают последовательности, которые перебирают значение, как если бы оно использовалось в цикле for/range. Новые методы Type.CanSeq и Type.CanSeq2 сообщают, будет ли вызов Value.Seq и Value.Seq2, соответственно, успешным без паники.

runtime/debug

Функция SetCrashOutput позволяет пользователю указать альтернативный файл, в который среда выполнения должна записать свой отчет о фатальном сбое. Его можно использовать для создания автоматизированного механизма отчетности для всех неожиданных сбоев, а не только для тех, которые находятся в goroutines, которые явно используют recovery.

runtime/pprof

Максимальная глубина стека для профилей alloc, mutex, block, threadcreate и goroutine была увеличена с 32 до 128 кадров.

runtime/trace

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

slices

Функция Repeat возвращает новый срез, который повторяет предоставленный срез указанное количество раз.

sync

Метод Map.Clear удаляет все записи, в результате чего получается пустая карта. Он аналогичен clear.

sync/atomic

Новые операторы And и Or применяют побитовое И или ИЛИ к заданным входным данным, возвращая старое значение.

syscall

Пакет syscall теперь определяет WSAENOPROTOOPT в Windows.

Функция GetsockoptInt теперь поддерживается в Windows.

testing/fstest

TestFS теперь возвращает структурированную ошибку, которую можно развернуть (с помощью метода Unwrap() []error). Это позволяет проверять ошибки с помощью error.Is или error.As.

text/template

Теперь шаблоны поддерживают новое действие "else with", что снижает сложность шаблона в некоторых случаях использования.

time

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

unicode/utf16

Функция RuneLen возвращает количество 16-битных слов в кодировке UTF-16 руны. Она возвращает -1, если руна не является допустимым значением для кодировки в UTF-16.

Порты

Darwin

Как было объявлено в примечаниях к выпуску Go 1.22, Go 1.23 требует macOS 11 Big Sur или более поздней версии; поддержка предыдущих версий прекращена.

Linux

Go 1.23 — последний релиз, требующий версию ядра Linux 2.6.32 или более позднюю. Go 1.24 потребует версию ядра Linux 3.17 или более позднюю, за исключением того, что системы под управлением 3.10 или более поздней версии будут по-прежнему поддерживаться, если ядро было исправлено для поддержки системного вызова getrandom.

OpenBSD

Go 1.23 добавляет экспериментальную поддержку OpenBSD на 64-битном RISC-V (GOOS=openbsd, GOARCH=riscv64).

ARM64

Go 1.23 вводит новую переменную среды GOARM64, которая указывает минимальную целевую версию архитектуры ARM64 во время компиляции. Допустимые значения: v8.{0-9} и v9.{0-5}. За этим может следовать параметр, указывающий расширения, реализованные целевым оборудованием. Допустимые параметры: ,lse и ,crypto.

Переменная среды GOARM64 по умолчанию — v8.0.

RISC-V

В Go 1.23 представлена новая переменная среды GORISCV64, которая выбирает профиль приложения пользовательского режима RISC-V для компиляции. Допустимые значения: rva20u64 и rva22u64.

Переменная среды GORISCV64 по умолчанию — rva20u64.

Wasm

Скрипт go_wasip1_wasm_exec в GOROOT/misc/wasm прекратил поддержку версий wasmtime < 14.0.0.


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


пятница, 17 мая 2024 г.

Релиз Go 1.22

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

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

Go 1.22 вносит два изменения в циклы for.

  • Раньше переменные, объявленные в цикле for, создавались один раз и обновлялись на каждой итерации. В Go 1.22 каждая итерация цикла создает новые переменные, чтобы избежать случайных ошибок совместного использования. Инструменты поддержки перехода, описанные в предложении, продолжают работать так же, как и в Go 1.21.
  • Циклы for теперь могут охватывать целые числа. Например:

    package main
    
    import "fmt"
    
    func main() {
      for i := range 10 {
        fmt.Println(10 - i)
      }
      fmt.Println("go1.22 has lift-off!")
    }
    

Go 1.22 включает предварительный просмотр изменения языка, которое рассматриваются для будущей версии Go: итераторы диапазона по функции. Сборка с использованием GOEXPERIMENT=rangefunc включает эту функцию.

Инструменты

Команда go

Команды в рабочих областях теперь могут использовать каталог vendor, содержащий зависимости рабочей области. Каталог создается go work vendor и используется командами сборки, когда для флага -mod установлено значение vendor, что является значением по умолчанию, когда присутствует каталог vendor рабочей области.

Обратите внимание, что содержимое каталога vendor для рабочей области отличается от содержимого каталога отдельного модуля: если каталог в корне рабочей области также содержит один из модулей в рабочей области, его каталог vendor может содержать зависимости либо рабочей области, либо модуль, но не оба.

go get больше не поддерживается за пределами модуля в устаревшем режиме GOPATH (то есть с GO111MODULE=off). Другие команды сборки, такие как go build и go test, будут продолжать работать в устаревших программах GOPATH в течение неопределенного времени.

go mod init больше не пытается импортировать требования к модулям из файлов конфигурации для других инструментов поставщиков (таких как Gopkg.lock).

go test -cover теперь печатает сводные данные о покрытии для покрываемых пакетов, у которых нет собственных тестовых файлов. До версии Go 1.22 при запуске go test -cover для такого пакета выдавалось сообщение
? mymod/mypack [no test files]
и теперь с Go 1.22 функции в пакете считаются непокрытыми:
mymod/mypack coverage: 0.0% of statements

? mymod/mypack [no test files]

Обратите внимание: если пакет вообще не содержит исполняемого кода, мы не можем сообщить о значимом проценте покрытия; для таких пакетов инструмент go будет продолжать сообщать об отсутствии тестовых файлов.

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

Trace

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

Эти улучшения применимы только для просмотра трассировок, созданных программами, созданными на Go 1.22 или новее. В будущем релизе некоторые из этих улучшений будут внесены в трассировки, создаваемые старой версией Go.

Go Vet

Ссылки на переменные цикла

Поведение инструмента vet изменилось, чтобы соответствовать новой семантике переменных цикла в Go 1.22. При анализе файла, для которого требуется Go 1.22 или новее (из-за файла go.mod или ограничения сборки для каждого файла), vet больше не сообщает о ссылках на переменные цикла внутри функционального литерала, которые могут пережить итерацию цикла. В Go 1.22 переменные цикла создаются заново для каждой итерации, поэтому такие ссылки больше не подвергаются риску использования переменной после ее обновления циклом.

Новые предупреждения об отсутствующих значениях после append

Инструмент vet теперь сообщает о вызовах append, которые не передают никаких значений для добавления к срезу, например slice = append(slice). Такое выражение не имеет никакого эффекта, и опыт показывает, что это почти всегда ошибка.

Новые предупреждения об отсрочке (defer) time.Since.

Инструмент vet теперь сообщает о неотложенном вызове time.Since(t) внутри оператора defer. Это эквивалентно вызову time.Now().Sub(t) перед оператором defer, а не при вызове отложенной функции. Почти во всех случаях правильный код требует отсрочки вызова time.Since. Например:

t := time.Now()
defer log.Println(time.Since(t)) // неотложенный вызов time.Since
tmp := time.Since(t); defer log.Println(tmp) // эквивалентно предыдущему defer

defer func() {
  log.Println(time.Since(t)) // корректно отложенный вызов time.Since
}()

Новые предупреждения о несовпадающих парах ключ-значение в вызовах log/slog.

Инструмент vet теперь сообщает о недопустимых аргументах при вызовах функций и методов в пакете структурированного журналирования log/slog, который принимает чередующиеся пары ключ/значение. Он сообщает о вызовах, в которых аргумент в ключевой позиции не является ни строкой, ни slog.Attr, и где в конечном ключе отсутствует свое значение.

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

Среда выполнения теперь хранит метаданные сборки мусора на основе типов ближе к каждому объекту кучи, улучшая производительность ЦП (задержку или пропускную способность) программ Go на 1–3%. Это изменение также снижает затраты памяти большинства программ Go примерно на 1% за счет дедупликации избыточных метаданных. В некоторых программах улучшение может быть меньшим, поскольку это изменение корректирует границы класса размера распределителя памяти, поэтому некоторые объекты могут быть перемещены на класс размера выше.

Следствием этого изменения является то, что адреса некоторых объектов, которые раньше всегда были выровнены по границе 16 байт (или выше), теперь будут выровнены только по границе 8 байт. Некоторые программы, использующие инструкции ассемблера, требующие, чтобы адреса памяти были выровнены по размеру более 8 байт и полагаются на предыдущее поведение выравнивания распределителя памяти, могут выйти из строя, но ожидается, что такие программы будут редкими. Такие программы могут быть созданы с использованием GOEXPERIMENT=noallocheaders, чтобы вернуться к старому макету метаданных и восстановить предыдущее поведение выравнивания, но владельцам пакетов следует обновить свой ассемблерный код, чтобы избежать предположения о выравнивании, поскольку этот обходной путь будет удален в будущем релизе.

В порте windows/amd64 программы, связывающие или загружающие библиотеки Go, созданные с помощью -buildmode=c-archive или -buildmode=c-shared, теперь могут использовать функцию SetUnhandledExceptionFilter Win32 для перехвата исключений, не обрабатываемых средой выполнения Go. Обратите внимание, что это уже поддерживалось в порте Windows/386.

Компилятор

Сборки оптимизации на основе профилей (PGO) теперь могут девиртуализировать большую часть вызовов, чем это было возможно ранее. Большинство программ из репрезентативного набора программ Go теперь видят улучшение во время выполнения от 2 до 14% от включения PGO.

Компилятор теперь чередует девиртуализацию и встраивание, поэтому вызовы методов интерфейса лучше оптимизированы.

Go 1.22 также включает предварительную версию расширенной реализации фазы встраивания компилятора, которая использует эвристику для повышения встраиваемости на местах вызовов, которые считаются "важными" (например, в циклах), и препятствует встраиванию на местах вызовов, которые считаются "неважными" (например, на пути паники). Сборка с использованием GOEXPERIMENT=newinliner позволяет использовать новую эвристику места вызова.

Линкер

Флаги -s и -w компоновщика теперь ведут себя более согласованно на всех платформах. Флаг -w подавляет генерацию отладочной информации DWARF. Флаг -s подавляет создание таблицы символов. Флаг -s также подразумевает флаг -w, который можно отменить с помощью -w=0. То есть -s -w=0 создаст двоичный файл с отладочной информацией DWARF, но без таблицы символов.

На платформах ELF флаг компоновщика -B теперь принимает специальную форму: с -B gobuildid компоновщик будет генерировать идентификатор сборки GNU (примечание ELF NT_GNU_BUILD_ID), полученный из идентификатора сборки Go.

В Windows при сборке с параметром -linkmode=internal компоновщик теперь сохраняет информацию SEH из объектных файлов C, копируя разделы .pdata и .xdata в окончательный двоичный файл. Это помогает при отладке и профилировании двоичных файлов с использованием собственных инструментов, таких как WinDbg. Обратите внимание, что до сих пор обработчики исключений SEH функций C не учитывались, поэтому это изменение может привести к тому, что некоторые программы будут вести себя по-другому. -linkmode=external это изменение не затрагивает, поскольку внешние компоновщики уже сохраняют информацию SEH.

Бутстрап

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

Основная библиотека

Новый пакет math/rand/v2

Go 1.22 включает первый пакет "v2" стандартной библиотеки — math/rand/v2. Наиболее важные изменения:

  • Метод Read, устаревший в math/rand, не был перенесен в math/rand/v2. (Он остается доступным в math/rand.) Подавляющее большинство вызовов Read должны использовать вместо этого Read crypto/rand. В противном случае можно создать пользовательский Read с использованием метода Uint64.
  • Глобальный генератор, к которому обращаются функции верхнего уровня, заполняется безусловно случайным образом. Поскольку API не гарантирует фиксированной последовательности результатов, теперь возможны такие оптимизации, как состояния генератора случайных чисел для каждого потока.
  • Интерфейс Source теперь имеет единственный метод Uint64; нет интерфейса Source64.
  • Многие методы теперь используют более быстрые алгоритмы, которые невозможно было применить в math/rand, поскольку они изменили выходные потоки.
  • Функции и методы верхнего уровня Intn, Int31, Int31n, Int63 и Int64n из math/rand в math/rand/v2 пишутся более идиоматично: IntN, Int32, Int32N, Int64 и Int64N. Также появились новые функции и методы верхнего уровня Uint32, Uint32N, Uint64, Uint64N, Uint и UintN.
  • Новая универсальная функция N похожа на Int64N или Uint64N, но работает для любого целочисленного типа. Например, случайная длительность от 0 до 5 минут равна rand.N(5*time.Minute).
  • Генератор LFSR Mitchell & Reeds, предоставленный math/rand Source, был заменен двумя более современными источниками псевдослучайного генератора: ChaCha8 и PCG. ChaCha8 — это новый, криптостойкий генератор случайных чисел, по эффективности примерно аналогичный PCG. ChaCha8 — это алгоритм, используемый для функций верхнего уровня в math/rand/v2. Начиная с Go 1.22, функции верхнего уровня math/rand (если они не заданы явно) и среда выполнения Go также используют ChaCha8 для случайности.

Планируется включить инструмент миграции API в будущую версию, скорее всего, в Go 1.23.

Новый пакет go/version

Новый пакет go/version реализует функции для проверки и сравнения строк версии Go.

Улучшенные шаблоны маршрутизации

HTTP-маршрутизация в стандартной библиотеке стала более выразительной. Шаблоны, используемые net/http.ServeMux, были улучшены и теперь принимают методы и подстановочные знаки.

Регистрация обработчика с помощью метода, например "POST/items/create", ограничивает вызовы обработчика запросами с данным методом. Шаблон с методом имеет приоритет над совпадающим шаблоном без него. В частном случае регистрация обработчика с помощью "GET" также регистрирует его с помощью "HEAD".

Подстановочные знаки в шаблонах, например /items/{id}, соответствуют сегментам URL-пути. Доступ к фактическому значению сегмента можно получить, вызвав метод Request.PathValue. Подстановочный знак, оканчивающийся на "...", например /files/{path...}, должен находиться в конце шаблона и соответствовать всем остальным сегментам.

Шаблон, оканчивающийся на "/", как всегда, соответствует всем путям, в которых он есть в качестве префикса. Чтобы точно соответствовать шаблону, включая косую черту, завершите его {$}, как в /exact/match/{$}.

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

Это изменение нарушает обратную совместимость в некоторых аспектах, некоторые из которых очевидны — шаблоны с "{" и "}" ведут себя по-другому, а некоторые — в меньшей степени — улучшена обработка экранированных путей. Изменение контролируется полем GODEBUG с именем httpmuxgo121. Установите httpmuxgo121=1, чтобы восстановить старое поведение.

Небольшие изменения в библиотеке

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

archive/tar

Новый метод Writer.AddFS добавляет в архив все файлы из fs.FS.

archive/zip

Новый метод Writer.AddFS добавляет в архив все файлы из fs.FS.

bufio

Когда SplitFunc возвращает ErrFinalToken с нулевым токеном, Scanner немедленно останавливается. Раньше перед остановкой он сообщал об окончательном пустом токене, что обычно было нежелательно. Вызывающие, которые хотят сообщить об окончательном пустом токене, могут сделать это, вернув []byte{}, а не nil.

cmp

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

crypto/tls

ConnectionState.ExportKeyingMaterial теперь будет возвращать ошибку, если не используется TLS 1.3 или расширение Extended_master_secret не поддерживается как сервером, так и клиентом. crypto/tls поддерживает это расширение начиная с Go 1.20. Это можно отключить с помощью параметра tlsunsafeekm=1 GODEBUG.

По умолчанию минимальной версией, предлагаемой серверами crypto/tls, теперь является TLS 1.2, если она не указана в config.MinimumVersion, что соответствует поведению клиентов crypto/tls. Это изменение можно отменить с помощью параметра tls10server=1 GODEBUG.

По умолчанию наборы шифров без поддержки ECDHE больше не предлагаются ни клиентами, ни серверами во время рукопожатий до TLS 1.3. Это изменение можно отменить с помощью настройки tlsrsakex=1 GODEBUG.

crypto/x509

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

В Android корневые сертификаты теперь будут загружаться из /data/misc/keychain/certs-added, а также из /system/etc/security/cacerts.

Новый тип OID поддерживает идентификаторы объектов ASN.1 с отдельными компонентами длиной более 31 бита. Новое поле, использующее этот тип, Policies, добавляется в структуру сертификата и теперь заполняется во время анализа. Любые OID, которые невозможно представить с помощью asn1.ObjectIdentifier, появятся в политиках, но не в старом поле PolicyIdentifiers. При вызове CreateCertificate поле Policies игнорируется, а политики берутся из поля PolicyIdentifiers. Использование параметра x509usepolicies=1 GODEBUG инвертирует это, заполняя политики сертификатов из поля Policies и игнорируя поле PolicyIdentifiers. Возможно изменение значения по умолчанию для x509usepolicies в Go 1.23, которое сделает Policies полем по умолчанию для маршалинга.

database/sql

Новый тип Null[T] предоставляет возможность сканирования столбцов, допускающих значение NULL, на предмет любых типов столбцов.

debug/elf

Константа R_MIPS_PC32 определена для использования с системами MIPS64.

Дополнительные константы R_LARCH_* определены для использования с системами LoongArch.

encoding

Новые методы AppendEncode и AppendDecode, добавленные к каждому из типов кодирования в пакетах  encoding/base32, encoding/base64 и encoding/hex, упрощают кодирование и декодирование из и в байтовые срезы, заботясь об управлении буфером байтовых срезов.

Методы base32.Encoding.WithPadding и base64.Encoding.WithPadding теперь вызывают панику, если аргумент заполнения имеет отрицательное значение, отличное от NoPadding.

encoding/json

Функции маршалинга и кодирования теперь экранируют символы '\b' и '\f' как \b и \f вместо \u0008 и \u000c.

go/ast

Следующие объявления, связанные с разрешением синтаксических идентификаторов, теперь устарели: Ident.Obj, Object, Scope, File.Scope, File.Unresolved, Importer, Package, NewPackage. В общем, идентификаторы не могут быть точно определены без информации о типе. Рассмотрим, например, идентификатор K в T{K: ""}: это может быть имя локальной переменной, если T является типом карты, или именем поля, если T является типом структуры. Новые программы должны использовать пакет go/types для разрешения идентификаторов.

Новая функция ast.Unparen удаляет из выражения все закрывающие круглые скобки.

go/types

Новый тип Alias представляет псевдонимы типов. Раньше псевдонимы типов не представлялись явно, поэтому ссылка на псевдоним типа была эквивалентна указанию псевдонима типа, и имя псевдонима терялось. Новое представление сохраняет промежуточный псевдоним. Это позволяет улучшить отчеты об ошибках (можно сообщить имя псевдонима типа) и позволяет лучше обрабатывать объявления циклических типов, включающие псевдонимы типов. В будущем выпуске типы псевдонимов также будут содержать информацию о параметрах типа. Новая функция Unalias возвращает фактический тип, обозначенный типом Alias (или любым другим типом, если на то пошло).

Поскольку типы псевдонимов могут нарушить работу существующих переключателей типов, которые не умеют их проверять, эта функциональность контролируется полем GODEBUG с именем gotypesalias. Если gotypesalias=0, все работает как прежде, и типы псевдонимов никогда не создаются. Если gotypesalias=1, создаются типы псевдонимов, и клиенты должны их ожидать. По умолчанию используется gotypesalias=0. В будущем релизе значение по умолчанию будет изменено на gotypesalias=1. Клиентам go/types настоятельно рекомендуется как можно скорее скорректировать свой код для работы с gotypesalias=1, чтобы устранить проблемы на раннем этапе.

Структура Info теперь экспортирует карту FileVersions, которая предоставляет информацию о версии Go для каждого файла.

Новый вспомогательный метод PkgNameOf возвращает имя локального пакета для данного объявления импорта.

Реализация SizesFor была скорректирована для вычисления тех же размеров типов, что и компилятор, когда аргументом компилятора SizesFor является "gc". Реализация Sizes по умолчанию, используемая средством проверки типов, теперь имеет вид Types.SizesFor("gc", "amd64").

Начальная позиция (Pos) блока лексического окружения (Scope), представляющего тело функции, изменилась: раньше она начиналась с открывающей фигурной скобки тела функции, но теперь начинается с функционального токена функции.

html/template

Литералы шаблонов Javascript теперь могут содержать действия шаблона Go, а анализ шаблона, содержащего такие действия, больше не будет возвращать ErrJSTemplate. Аналогично, параметр jstmpllitinterp в GODEBUG больше не имеет никакого эффекта.

io

Новый метод SectionReader.Outer возвращает ReaderAt, смещение и размер, переданные в NewSectionReader.

log/slog

Новая функция SetLogLoggerLevel контролирует уровень моста между пакетами `slog` и `log`. Он устанавливает минимальный уровень для вызовов функций ведения журнала `slog` верхнего уровня, а также устанавливает уровень для вызовов `log.Logger`, которые проходят через `slog`.

math/big

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

net

Когда io.Copy копирует из TCPConn в UnixConn, он теперь будет использовать системный вызов Linux splice(2), если это возможно, используя новый метод TCPConn.WriteTo.

DNS-резольвер Go, используемый при сборке с "-tags=netgo", теперь ищет соответствующее имя в файле хостов Windows, расположенном по адресу %SystemRoot%\System32\drivers\etc\hosts, перед выполнением DNS-запроса.

net/http

Новые функции ServeFileFS, FileServerFS и NewFileTransportFS являются версиями существующих ServeFile, FileServer и NewFileTransport, работающих на fs.FS.

HTTP-сервер и клиент теперь отклоняют запросы и ответы, содержащие недопустимый пустой заголовок Content-Length. Предыдущее поведение можно восстановить, установив поле GODEBUG httplaxcontentlength=1.

Новый метод Request.PathValue возвращает значения подстановочных знаков пути из запроса, а новый метод Request.SetPathValue устанавливает значения подстановочных знаков пути в запросе.

net/http/cgi

При выполнении процесса CGI переменной PATH_INFO теперь всегда присваивается пустая строка или значение, начинающееся с символа /, как того требует RFC 3875. Ранее для некоторых комбинаций Handler.Root и URL-адреса запроса было возможно нарушить это требование.

net/netip

Новый метод AddrPort.Compare сравнивает два AddrPort.

os

В Windows функция Stat теперь следует за всеми точками повторной обработки, которые ссылаются на другой именованный объект в системе. Раньше он следовал только за точками повторной обработки IO_REPARSE_TAG_SYMLINK и IO_REPARSE_TAG_MOUNT_POINT.

В Windows передача O_SYNC в OpenFile теперь приводит к тому, что операции записи передаются непосредственно на диск, что эквивалентно O_SYNC на платформах Unix.

В Windows функции ReadDir, File.ReadDir, File.Readdir и File.Readdirnames теперь считывают записи каталога в пакетном режиме, чтобы сократить количество системных вызовов, повышая производительность до 30%.

Когда io.Copy копирует из файла в net.UnixConn, он теперь будет использовать системный вызов Linux sendfile(2), если это возможно, используя новый метод File.WriteTo.

os/exec

В Windows LookPath теперь игнорирует пустые записи в %PATH% и возвращает ErrNotFound (вместо ErrNotExist), если не найдено расширение исполняемого файла для разрешения однозначного имени.

В Windows Command и Cmd.Start больше не вызывают LookPath, если путь к исполняемому файлу уже является абсолютным и имеет расширение исполняемого файла. Кроме того, Cmd.Start больше не записывает разрешенное расширение обратно в поле Path, поэтому теперь можно безопасно вызывать метод String одновременно с вызовом Start.

reflect

Метод Value.IsZero теперь возвращает true для числа с плавающей запятой или комплексного отрицательного нуля, а также возвращает true для значения структуры, если пустое поле (поле с именем _) каким-то образом имеет ненулевое значение. Эти изменения делают IsZero совместимым со сравнением значения с нулем с помощью оператора языка ==.

Функция PtrTo устарела в пользу PointerTo.

Новая функция TypeFor возвращает Type, который представляет аргумент типа T. Раньше, чтобы получить значение Reflect.Type для типа, нужно было использовать Reflect.TypeOf((*T)(nil)).Elem(). Теперь это можно записать как reflect.TypeFor[T]().

runtime/metrics

Четыре новых показателя гистограммы /sched/pauses/stopping/gc:seconds, /sched/pauses/stopping/other:seconds, /sched/pauses/total/gc:seconds и /sched/pauses/total/other:seconds предоставляют дополнительные подробности о паузах, связанных с остановкой мира. Метрики "остановки" сообщают о времени, прошедшем от принятия решения об остановке мира до остановки всех горутин. "Общие" показатели сообщают о времени, прошедшем от принятия решения остановить мир до его повторного запуска.

Метрика /gc/pauses:seconds устарела, поскольку она эквивалентна новой метрике /sched/pauses/total/gc:seconds.

/sync/mutex/wait/total:seconds теперь включают в себя конфликты по внутренним блокировкам времени выполнения в дополнение к sync.Mutex и sync.RWMutex.

runtime/pprof

Профили мьютексов теперь масштабируют конкуренцию по количеству горутин, заблокированных во мьютексе. Это обеспечивает более точное представление о степени, в которой мьютекс является узким местом в программе Go. Например, если 100 горутин заблокированы мьютексом на 10 миллисекунд, профиль мьютекса теперь будет записывать задержку в 1 секунду вместо задержки в 10 миллисекунд.

Профили мьютексов теперь также включают конкуренцию за внутренние блокировки во время выполнения в дополнение к sync.Mutex и sync.RWMutex. Конфликт по внутренним блокировкам во время выполнения всегда сообщается во время runtime._LostContendedRuntimeLock. В будущих версиях в этих случаях будут добавлены полные трассировки стека.

Профили ЦП на платформах Darwin теперь содержат карту памяти процесса, что позволяет просматривать дизассемблирование в инструменте pprof.

runtime/trace

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

Трассировки выполнения теперь используют часы операционной системы на большинстве платформ (за исключением Windows), поэтому их можно сопоставить со трассировками, создаваемыми компонентами более низкого уровня. Трассировки выполнения больше не зависят от надежности часов платформы для создания правильной трассировки. Трассировки выполнения теперь регулярно секционируются на лету и, как следствие, могут обрабатываться в потоковом режиме. Трассировки выполнения теперь содержат полную длительность всех системных вызовов. Трассировки выполнения теперь содержат информацию о потоках операционной системы, в которых выполнялись горутины. Влияние задержки при запуске и остановке трассировки выполнения было значительно уменьшено. Трассировки выполнения теперь могут начинаться или заканчиваться на этапе метки сборки мусора.

Чтобы разработчики Go могли воспользоваться этими улучшениями, по адресу golang.org/x/exp/trace доступен экспериментальный пакет для чтения трассировки. Обратите внимание, что этот пакет работает только с трассировками, созданными программами, созданными на данный момент с помощью Go 1.22.

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

slices

Новая функция Concat объединяет несколько срезов.

Функции, уменьшающие размер среза (Delete, DeleteFunc, Compact, CompactFunc и Replace), теперь обнуляют элементы между новой длиной и старой длиной.

Команда Insert теперь всегда вызывает панику, если аргумент i выходит за пределы допустимого диапазона. Раньше в этой ситуации не паниковало, если не было элементов для вставки.

syscall

Пакет системных вызовов был заморожен начиная с Go 1.4 и помечен как устаревший в Go 1.11, из-за чего многие редакторы предупреждают о любом использовании пакета. Однако для некоторых неустаревших функций требуется использование пакета syscall, например поля os/exec.Cmd.SysProcAttr. Чтобы избежать ненужных жалоб на такой код, пакет syscall больше не помечается как устаревший. Пакет остается замороженным для большинства новых функций, и в новом коде по-прежнему рекомендуется использовать golang.org/x/sys/unix или golang.org/x/sys/windows, где это возможно.

В Linux новое поле SysProcAttr.PidFD позволяет получить PID FD при запуске дочернего процесса через StartProcess или os/exec.

В Windows передача O_SYNC в Open теперь приводит к тому, что операции записи передаются непосредственно на диск, что эквивалентно O_SYNC на платформах Unix.

testing/slogtest

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

Порты

Darwin

В macOS на 64-битной архитектуре x86 (порт darwin/amd64) набор инструментов Go теперь по умолчанию генерирует позиционно-независимые исполняемые файлы (PIE). Двоичные файлы, отличные от PIE, можно создать, указав флаг сборки -buildmode=exe. В 64-битной macOS на базе ARM (порт darwin/arm64) набор инструментов Go уже генерирует PIE по умолчанию.

Go 1.22 — последний релиз, который будет работать на macOS 10.15 Catalina. Для Go 1.23 потребуется macOS 11 Big Sur или более поздняя версия.

Arm

Переменная среды GOARM теперь позволяет вам выбирать, использовать ли программную или аппаратную плавающую запятую. Раньше допустимыми значениями GOARM были 5, 6 или 7. Теперь за этими же значениями можно опционально следовать ,softfloat или ,hardfloat для выбора реализации с плавающей запятой.

Эта новая опция по умолчанию имеет мягкое плавание для версии 5 и жесткое плавание для версий 6 и 7.

Loong64

Порт loong64 теперь поддерживает передачу аргументов функции и результатов с использованием регистров.

Порт linux/loong64 теперь поддерживает очистку адресов, очистку памяти, перемещение компоновщика нового стиля и режим сборки плагинов.

OpenBSD

В Go 1.22 добавлен экспериментальный порт OpenBSD на 64-битном PowerPC с прямым порядком байтов (openbsd/ppc64).


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