среда, 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.


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


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

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