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


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


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

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