вторник, 21 февраля 2023 г.

Релиз Go 1.20

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

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

Go 1.20 включает четыре изменения языка.

В Go 1.17 добавлены преобразования из среза в указатель массива. Go 1.20 расширяет это, чтобы разрешить преобразования из среза в массив: для среза x теперь можно записать [4]byte(x) вместо *(*[4]byte)(x).

Пакет unsafe определяет три новые функции SliceData, String и StringData. Наряду с Slice из Go 1.17 эти функции теперь предоставляют полную возможность конструировать и деконструировать значения срезов и строк, не завися от их точного представления.

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

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

Порты


Windows

Go 1.20 — это последний релиз, который будет работать в любой версии Windows 7, 8, Server 2008 и Server 2012. Для Go 1.21 потребуется как минимум Windows 10 или Server 2016.

Darwin и iOS

Go 1.20 — это последний релиз, который будет работать на macOS 10.13 High Sierra или 10.14 Mojave. Go 1.21 потребует macOS 10.15 Catalina или более поздней версии.

FreeBSD/RISC-V

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

Инструменты


Команда go

Каталог $GOROOT/pkg больше не хранит предварительно скомпилированные архивы пакетов для стандартной библиотеки: go install больше не записывает их, сборка go больше не проверяет их, и дистрибутив Go больше не отправляет их. Вместо этого пакеты в стандартной библиотеке собираются по мере необходимости и кэшируются в кэше сборки, как и пакеты вне GOROOT. Это изменение уменьшает размер дистрибутива Go, а также позволяет избежать перекоса инструментальной цепочки C для пакетов, использующих cgo.

Реализация go test -json была улучшена, чтобы сделать ее более надежной. Программы, запускающие go test -json, не нуждаются в каких-либо обновлениях. Программы, которые напрямую вызывают инструмент go test2json, теперь должны запускать двоичный файл теста с параметром -v=test2json (например, go test -v=test2json или ./pkg.test -test.v=test2json) вместо простого -v.

Связанное с этим изменение для go test -json — это добавление события с набором действий для запуска в начале выполнения каждой тестовой программы. При запуске нескольких тестов с помощью команды go эти стартовые события гарантированно будут генерироваться в том же порядке, что и пакеты, указанные в командной строке.

Команда go теперь определяет теги построения функций архитектуры, такие как amd64.v2, чтобы позволить выбрать файл реализации пакета на основе наличия или отсутствия конкретной функции архитектуры.

Подкоманды go теперь принимают -C <dir> для изменения каталога на <dir> перед выполнением команды, что может быть полезно для сценариев, которым необходимо выполнять команды в нескольких разных модулях.

Команды go build и go test больше не принимают флаг -i, который устарел, начиная с Go 1.16.

Команда go generate теперь принимает -skip <pattern> для пропуска директив //go:generate, соответствующих <pattern>.

Команда go test теперь принимает параметр -skip <pattern>, чтобы пропустить тесты, подтесты или примеры, соответствующие <pattern>.

Когда основной модуль находится в GOPATH/src, go install больше не устанавливает библиотеки для неосновных пакетов в GOPATH/pkg, а go list больше не сообщает поле Target для таких пакетов. (В модульном режиме скомпилированные пакеты хранятся только в кэше сборки, но из-за ошибки цели установки GOPATH неожиданно остались в силе.)

Команды go build, go install и другие, связанные со сборкой, теперь поддерживают флаг -pgo, который включает оптимизацию на основе профиля. Флаг -pgo указывает путь к файлу профиля. Указание -pgo=auto заставляет команду go искать файл с именем default.pgo в каталоге пакета main и использовать его, если он есть. В настоящее время для этого режима требуется, чтобы в командной строке был указан один main пакет, но планируется снять это ограничение в будущем релизе. Указание -pgo=off отключает оптимизацию на основе профиля.

Команды go build, go install и другие команды, связанные со сборкой, теперь поддерживают флаг -cover, который выполняет сборку указанной цели с инструментированием покрытия кода.

go version

Команда go version -m теперь поддерживает чтение дополнительных типов двоичных файлов Go, в первую очередь библиотек DLL Windows, созданных с помощью go build -buildmode=c-shared, и двоичных файлов Linux без разрешения на выполнение.

Cgo

Команда go теперь отключает cgo по умолчанию в системах без цепочки инструментов C. В частности, когда переменная среды CGO_ENABLED не установлена, переменная среды CC не установлена, а компилятор C по умолчанию (обычно clang или gcc) не найден в пути, CGO_ENABLED по умолчанию имеет значение 0. Как всегда, вы можете переопределить значение по умолчанию, установка CGO_ENABLED явно.

Наиболее важным эффектом изменения по умолчанию является то, что когда Go устанавливается в системе без компилятора C, теперь он будет использовать чистые сборки Go для пакетов в стандартной библиотеке, которые используют cgo, вместо использования предустановленных архивов пакетов (которые были удалены, как указано выше) или попытки использовать cgo и неудаче при этом. Это позволяет Go лучше работать в некоторых средах с минимальным контейнером, а также в macOS, где предустановленные архивы пакетов не использовались для пакетов на основе cgo, начиная с версии Go 1.16.

Пакеты в стандартной библиотеке, использующие cgo, это net, os/user и plugin. В macOS пакеты net и os/user были переписаны, чтобы не использовать cgo: теперь один и тот же код используется для сборок cgo и не-cgo, а также кросс-компилируемых сборок. В Windows пакеты net и os/user никогда не использовали cgo. В других системах сборки с отключенным cgo будут использовать чистую версию Go этих пакетов.

В macOS детектор гонок был переписан, чтобы не использовать cgo: программы с включенным детектором гонок можно создавать и запускать без Xcode. В Linux и других системах Unix, а также в Windows для использования детектора гонки требуется цепочка инструментов C на хосте.

Cover (Покрытие)

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

Чтобы собрать данные о покрытии для программы, соберите ее с флагом -cover команды go build, затем запустите полученный двоичный файл с переменной среды GOCOVERDIR, установленной в выходной каталог для профилей покрытия.

Ветеринар (vet)

Улучшено обнаружение захвата переменных цикла вложенными функциями.

Инструмент vet теперь сообщает о ссылках на переменные цикла после вызова T.Parallel() в телах функций подтеста. В таких ссылках может наблюдаться значение переменной из другой итерации (что обычно приводит к пропуску тестовых случаев) или недопустимое состояние из-за несинхронизированного конкурентного доступа.

Инструмент также обнаруживает ошибки ссылок в большем количестве мест. Раньше он рассматривал только последний оператор тела цикла, но теперь он рекурсивно проверяет последние операторы в операторах if, switch и select.

Новая диагностика для некорректных форматов времени

Инструмент vet теперь сообщает об использовании формата времени 2006-02-01 (гггг-дд-мм) с Time.Format и time.Parse. Этот формат не встречается в общих стандартах даты, но часто используется по ошибке при попытке использовать формат даты ISO 8601 (гггг-мм-дд).

Runtime

Некоторые из внутренних структур данных сборщика мусора были реорганизованы, чтобы освободить больше места и CPU. Это изменение снижает нагрузку на память и повышает общую производительность процессора до 2%.

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

Go 1.20 добавляет новый пакет runtime/coverage, содержащий API для записи данных профиля покрытия во время выполнения из долго работающих и/или серверных программ, которые не завершаются через os.Exit().

Компилятор

В Go 1.20 добавлена предварительная поддержка оптимизации на основе профиля (PGO). PGO позволяет цепочке инструментов выполнять оптимизацию для конкретных приложений и рабочих нагрузок на основе информации о профиле времени выполнения. В настоящее время компилятор поддерживает профили CPU pprof, которые можно собирать обычными средствами, такими как пакеты runtime/pprof или net/http/pprof. Чтобы включить PGO, передайте путь к файлу профиля pprof через флаг -pgo, чтобы начать сборку, как указано выше. Go 1.20 использует PGO для более агрессивного встраивания функций в местах горячих вызовов. Тесты для репрезентативного набора программ Go показывают, что включение оптимизации встраивания на основе профиля повышает производительность примерно на 3–4%. Планируется добавить больше оптимизаций на основе профилей в будущих релизах. Обратите внимание, что оптимизация на основе профилей является предварительной версией, поэтому используйте ее с осторожностью.

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

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

В Go 1.18 и 1.19 наблюдался регресс в скорости сборки, в основном из-за добавления поддержки дженериков и последующей работы. Go 1.20 повышает скорость сборки до 10 %, возвращая ее в соответствие с Go 1.17. По сравнению с Go 1.19 производительность сгенерированного кода также в целом немного улучшилась.

Линкер (компоновщик)

В Linux компоновщик теперь выбирает динамический интерпретатор для glibc или musl во время компоновки.

В Windows компоновщик Go теперь поддерживает современные наборы инструментов C на основе LLVM.

Go 1.20 использует префиксы go: и type: для символов, сгенерированных компилятором, а не go. и type. . Это позволяет избежать путаницы для пользовательских пакетов, имя которых начинается с go. . Пакет debug/gosym понимает это новое соглашение об именах для двоичных файлов, созданных с помощью Go 1.20 и новее.

Начальная загрузка (Bootstrap)

При сборке релиза Go из исходного кода и не заданном GOROOT_BOOTSTRAP предыдущие версии Go искали цепочку инструментов начальной загрузки Go 1.4 или более поздней версии в каталоге $HOME/go1.4 (%HOMEDRIVE%%HOMEPATH%\go1.4 в Windows). Go 1.18 и Go 1.19 сначала искали $HOME/go1.17 или $HOME/sdk/go1.17, а затем возвращались к $HOME/go1.4, ожидая, что Go 1.17 потребуется для использования при начальной загрузке Go 1.20. Go 1.20 требует версии Go 1.17 для начальной загрузки, но стало понятно, что следует использовать последнюю точечную версию цепочки инструментов начальной загрузки, поэтому для нее требуется Go 1.17.13. Go 1.20 ищет $HOME/go1.17.13 или $HOME/sdk/go1.17.13, прежде чем вернуться к $HOME/go1.4 (для поддержки систем, которые жестко запрограммировали путь $HOME/go1.4, но установили более новый Go туда). В будущем планируется продвигать цепочку инструментов начальной загрузки примерно раз в год, и, в частности, ожидается, что Go 1.22 потребует финальной версии Go 1.20 для начальной загрузки.

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


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

Go 1.20 добавляет новый пакет crypto/ecdh для обеспечения явной поддержки обмена ключами Диффи-Хеллмана на эллиптических кривых по кривым NIST и Curve25519.

Программы должны использовать crypto/ecdh вместо функций более низкого уровня в crypto/elliptic для ECDH и сторонние модули для более продвинутых вариантов использования.

Обертывание нескольких ошибок

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

Ошибка e может обернуть более одной ошибки, предоставив метод Unwrap, который возвращает []error.

Функции errors.Is и errors.As были обновлены для проверки многократно обернутых ошибок.

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

Новая функция errors.Join возвращает ошибку, обертывающую список ошибок.

HTTP ResponseController

Новый тип "net/http".ResponseController предоставляет доступ к расширенным функциям для каждого запроса, которые не обрабатываются интерфейсом "net/http".ResponseWriter.

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

Тип ResponseController обеспечивает более понятный и удобный способ добавления элементов управления для каждого обработчика. В Go 1.20 также добавлены два таких элемента управления: SetReadDeadline и SetWriteDeadline, которые позволяют устанавливать крайние сроки чтения и записи для каждого запроса. Например:

func RequestHandler(w ResponseWriter, r *Request) {
  rc := http.NewResponseController(w)
  rc.SetWriteDeadline(time.Time{}) // отключаем Server.WriteTimeout при отправке большого ответа
  io.Copy(w, bigData)
}

Новый хук ReverseProxy Rewrite

Прокси-сервер пересылки httputil.ReverseProxy включает новую функцию хука Rewrite, заменяющую предыдущий хук Director.

Хук Rewrite принимает параметр ProxyRequest, который включает в себя как входящий запрос, полученный прокси-сервером, так и исходящий запрос, который он отправит. В отличие от хуков Director, которые работают только с исходящим запросом, это позволяет хукам Rewrite избегать определенных сценариев, когда злонамеренный входящий запрос может привести к удалению заголовков, добавленных хуком, перед пересылкой.

Метод ProxyRequest.SetURL направляет исходящий запрос в указанное место назначения и заменяет функцию NewSingleHostReverseProxy. В отличие от NewSingleHostReverseProxy, SetURL также устанавливает заголовок узла исходящего запроса.

Метод ProxyRequest.SetXForwarded устанавливает заголовки X-Forwarded-For, X-Forwarded-Host и X-Forwarded-Proto исходящего запроса. При использовании Rewrite эти заголовки не добавляются по умолчанию.

Пример хука Rewrite, использующего эти функции:

proxyHandler := &httputil.ReverseProxy{
  Rewrite: func(r *httputil.ProxyRequest) {
    r.SetURL(outboundURL) // Перенаправить запрос на исходящий URL.
    r.SetXForwarded()     //  Установить заголовки X-Forwarded-*.
    r.Out.Header.Set("X-Additional-Header", "header set by the proxy")
  },
}

ReverseProxy больше не добавляет заголовок User-Agent к пересылаемым запросам, если во входящем запросе его нет.

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

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

archive/tar

Если установлена переменная среды GODEBUG=tarinsecurepath=0, метод Reader.Next теперь будет возвращать ошибку ErrInsecurePath для записи с именем файла, которое является абсолютным путем, ссылается на расположение за пределами текущего каталога, содержит недопустимые символы или (в Windows) — это зарезервированное имя, такое как NUL. В будущей версии Go небезопасные пути могут быть отключены по умолчанию.

archive/zip

Если установлена переменная окружения GODEBUG=zipinsecurepath=0, NewReader теперь будет возвращать ошибку ErrInsecurePath при открытии архива, содержащего любое имя файла, которое является абсолютным путем, ссылается на расположение за пределами текущего каталога, содержит недопустимые символы или (на Windows) — это зарезервированные имена, такие как NUL. В будущей версии Go небезопасные пути могут быть отключены по умолчанию.

Чтение из файла каталога, содержащего данные файла, теперь будет возвращать ошибку. Спецификация zip не позволяет файлам каталогов содержать файловые данные, поэтому это изменение влияет только на чтение из недопустимых архивов.

bytes

Новые функции CutPrefix и CutSuffix похожи на TrimPrefix и TrimSuffix, но также сообщают, была ли строка обрезана.

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

context

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

crypto/ecdsa

При использовании поддерживаемых кривых все операции теперь выполняются за постоянное время. Это привело к увеличению процессорного времени от 5% до 30%, в основном затронув P-384 и P-521.

Новый метод PrivateKey.ECDH преобразует ecdsa.PrivateKey в ecdh.PrivateKey.

crypto/ed25519

Метод PrivateKey.Sign и функция VerifyWithOptions теперь поддерживают подписание предварительно хэшированных сообщений с помощью Ed25519ph, на что указывает Options.HashFunc, возвращающий crypto.SHA512. Кроме того, теперь они поддерживают Ed25519ctx и Ed25519ph с контекстом, указанным в новом поле Options.Context.

crypto/rsa

Новое поле OAEPOptions.MGFHash позволяет отдельно настроить хэш MGF1 для расшифровки OAEP.

crypto/rsa теперь использует новый, более безопасный бекенд с постоянным временем. Это приводит к увеличению времени выполнения ЦП для операций расшифровки примерно на 15% (RSA-2048 на amd64) до 45% (RSA-4096 на arm64) и больше на 32-разрядных архитектурах. Операции шифрования примерно в 20 раз медленнее, чем раньше (но все же в 5-10 раз быстрее, чем дешифрование). Ожидается, что производительность улучшится в будущих релизах. Программы не должны изменять или создавать вручную поля PrecomputedValues.

crypto/subtle

Новая функция XORBytes XOR объединяет два байтовых среза.

crypto/tls

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

При сбое рукопожатия из-за сбоя проверки сертификата клиент и сервер TLS теперь возвращают ошибку нового типа CertificateVerificationError, которая включает представленные сертификаты.

crypto/x509

ParsePKCS8PrivateKey и MarshalPKCS8PrivateKey теперь поддерживают ключи типа *crypto/ecdh.PrivateKey. ParsePKIXPublicKey и MarshalPKIXPublicKey теперь поддерживают ключи типа *crypto/ecdh.PublicKey. Анализ ключей кривой NIST по-прежнему возвращает значения типа *ecdsa.PublicKey и *ecdsa.PrivateKey. Используйте их новые методы ECDH для преобразования в типы crypto/ecdh.

Новая функция SetFallbackRoots позволяет программе определить набор резервных корневых сертификатов на случай, если верификатор операционной системы или стандартный корневой пакет платформы недоступен во время выполнения. Чаще всего он будет использоваться с новым пакетом golang.org/x/crypto/x509roots/fallback, который предоставит обновленный корневой пакет.

debug/elf

Попытки чтения из раздела SHT_NOBITS с помощью Section.Data или средства чтения, возвращенного Section.Open, теперь возвращают ошибку.

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

Дополнительные константы R_PPC64_* определены для использования с перемещениями PPC64 ELFv2.

Значение константы для R_PPC64_SECTOFF_LO_DS исправлено с 61 на 62.

debug/gosym

В связи с изменением правил именования символов Go инструменты, обрабатывающие двоичные файлы Go, должны использовать пакет debug/gosym версии 1.20 для прозрачной обработки как старых, так и новых двоичных файлов.

debug/pe

Дополнительные константы IMAGE_FILE_MACHINE_RISCV* определены для использования с системами RISC-V.

encoding/binary

Функции ReadVarint и ReadUvarint теперь будут возвращать io.ErrUnexpectedEOF после чтения частичного значения, а не io.EOF.

encoding/xml

Новый метод Encoder.Close можно использовать для проверки незакрытых элементов после завершения кодирования.

Теперь декодер отклоняет имена элементов и атрибутов, содержащие более одного двоеточия, такие как <a:b:c>, а также пространства имен, которые разрешаются в пустую строку, например xmlns:a="".

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

errors

Новая функция Join возвращает ошибку, обертывающую список ошибок.

fmt

Функция Errorf поддерживает несколько вхождений глагола формата %w, возвращая ошибку, которая разворачивается в список всех аргументов %w.

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

go/ast

Новое поле RangeStmt.Range записывает положение ключевого слова диапазона в операторе диапазона.

В новых полях File.FileStart и File.FileEnd записывается положение начала и конца всего исходного файла.

go/token

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

go/types

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

io

Новый OffsetWriter является оболочкой базового WriterAt и предоставляет методы Seek, Write и WriteAt, которые корректируют их эффективную позицию смещения в файле на фиксированную величину.

io/fs

Новая ошибка SkipAll немедленно, но успешно завершает WalkDir.

math/big

Широкая область применения пакета math/big и время, зависящее от ввода, делают его плохо подходящим для реализации криптографии. Пакеты криптографии в стандартной библиотеке больше не вызывают нетривиальные методы Int для входных данных, контролируемых злоумышленником. В будущем определение того, считается ли ошибка в math/big уязвимостью системы безопасности, будет зависеть от ее более широкого влияния на стандартную библиотеку.

math/rand

Пакет math/rand теперь автоматически заполняет глобальный генератор случайных чисел (используемый функциями верхнего уровня, такими как Float64 и Int) случайным значением, а функция Seed верхнего уровня устарела. Программы, которым нужна воспроизводимая последовательность случайных чисел, должны предпочитать выделять свой собственный источник случайных чисел, используя rand.New(rand.NewSource(seed)).

Программы, которым требуется более раннее последовательное глобальное заполнение, могут установить GODEBUG=randautoseed=0 в своей среде.

Функция чтения верхнего уровня устарела. Почти во всех случаях лучше подходит crypto/rand.Read.

mime

Функция ParseMediaType теперь позволяет дублировать имена параметров, если значения имен совпадают.

mime/multipart

Методы типа Reader теперь оборачивают ошибки, возвращаемые базовым io.Reader.

net

Функция LookupCNAME теперь последовательно возвращает содержимое записи CNAME, если она существует. Раньше в системах Unix и при использовании чистого преобразователя Go функция LookupCNAME возвращала ошибку, если запись CNAME ссылалась на имя без записи A, AAAA или CNAME. Это изменение изменяет LookupCNAME, чтобы оно соответствовало предыдущему поведению в Windows, позволяя успешно выполнять LookupCNAME всякий раз, когда CNAME существует.

Interface.Flags теперь включает новый флаг FlagRunning, указывающий на операционно активный интерфейс. Для интерфейса, настроенного административно, но неактивного (например, из-за того, что сетевой кабель не подключен), будет установлен FlagUp, но не FlagRunning.

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

Сопоставитель Go DNS распознает вариант сопоставителя trust-ad. Когда в resolv.conf установлены параметры trust-ad, преобразователь Go будет устанавливать бит AD в DNS-запросах. Преобразователь не использует бит AD в ответах.

Разрешение DNS обнаружит изменения в /etc/nsswitch.conf и перезагрузит файл при его изменении. Проверки выполняются не чаще одного раза каждые пять секунд, что соответствует предыдущей обработке файлов /etc/hosts и /etc/resolv.conf.

net/http

Функция ResponseWriter.WriteHeader теперь поддерживает отправку кодов состояния 1xx.

Новый параметр конфигурации Server.DisableGeneralOptionsHandler позволяет отключить обработчик OPTIONS * по умолчанию.

Новый хук Transport.OnProxyConnectResponse вызывается, когда Transport получает HTTP-ответ от прокси-сервера на запрос CONNECT.

HTTP-сервер теперь принимает запросы HEAD, содержащие тело, а не отклоняет их как недействительные.

Ошибки потока HTTP/2, возвращаемые функциями net/http, могут быть преобразованы в golang.org/x/net/http2.StreamError с помощью errors.As.

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

net/netip

Новые функции IPv6LinkLocalAllRouters и IPv6Loopback являются эквивалентами net/netip функций net.IPv6loopback и net.IPv6linklocalallrouters.

os

В Windows имя NUL больше не рассматривается как особый случай в Mkdir и Stat.

В Windows File.Stat теперь использует дескриптор файла для получения атрибутов, когда файл является каталогом. Ранее он использовал путь, переданный в Open, который больше не может быть файлом, представленным дескриптором файла, если файл был перемещен или заменен. Это изменение изменяет Open для открытия каталогов без доступа FILE_SHARE_DELETE, что соответствует поведению обычных файлов.

В Windows File.Seek теперь поддерживает поиск в начале каталога.

os/exec

Новые поля Cmd Cancel и WaitDelay определяют поведение Cmd, когда связанный с ним контекст отменяется или его процесс завершается, а каналы ввода-вывода остаются открытыми дочерним процессом.

path/filepath

Новая ошибка SkipAll немедленно, но успешно завершает Walk.

Новая функция IsLocal сообщает, является ли путь лексически локальным для каталога. Например, если IsLocal(p) имеет значение true, то Open(p) будет ссылаться на файл, который лексически находится внутри поддерева с корнем в текущем каталоге.

reflect

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

Новый метод Value.Grow расширяет срез, чтобы гарантировать место для других n элементов.

Новый метод Value.SetZero задает нулевое значение для своего типа.

Go 1.18 представил методы Value.SetIterKey и Value.SetIterValue. Это оптимизации: v.SetIterKey(it) должен быть эквивалентен v.Set(it.Key()). Реализации ошибочно пропускали проверку на использование неэкспортированных полей, которая присутствовала в неоптимизированных формах. Go 1.20 исправляет эти методы, чтобы включить проверку неэкспортированных полей.

regexp

Go 1.19.2 и Go 1.18.7 включали исправление безопасности для синтаксического анализатора регулярных выражений, заставляющее его отклонять очень большие выражения, которые потребляли бы слишком много памяти. Поскольку релизы исправлений Go не вводят новый API, синтаксический анализатор в этом случае вернул синтаксис.ErrInternalError. В Go 1.20 добавлена более конкретная ошибка syntax.ErrLarge, которую теперь возвращает синтаксический анализатор.

runtime/cgo

Go 1.20 добавляет новый тип маркера Incomplete. Код, сгенерированный cgo, будет использовать cgo.Incomplete для обозначения неполного типа C.

runtime/metrics

Go 1.20 добавляет новые поддерживаемые метрики, включая текущую настройку GOMAXPROCS (/sched/gomaxprocs:threads), количество выполненных вызовов cgo (/cgo/go-to-c-calls:calls), общее время блокировки мьютекса (/sync/mutex/wait/total:seconds) и различные меры времени, потраченного на сборку мусора.

Метрики гистограмм на основе времени теперь менее точны, но занимают гораздо меньше памяти.

runtime/pprof

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

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

runtime/trace

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

strings

Новые функции CutPrefix и CutSuffix похожи на TrimPrefix и TrimSuffix, но также сообщают, была ли строка обрезана.

sync

Новые методы Map Swap, CompareAndSwap и CompareAndDelete позволяют автоматически обновлять существующие записи карты.

syscall

Во FreeBSD прокладки совместимости, необходимые для FreeBSD 11 и более ранних версий, были удалены.

В Linux определены дополнительные константы CLONE_* для использования с полем SysProcAttr.Cloneflags.

В Linux новые поля SysProcAttr.CgroupFD и SysProcAttr.UseCgroupFD позволяют поместить дочерний процесс в определенную контрольную группу.

testing

Новый метод B.Elapsed сообщает о текущем прошедшем времени эталонного теста, что может быть полезно для расчета показателей для отчета с помощью ReportMetric.

time

Новые константы макета времени DateTime, DateOnly и TimeOnly предоставляют имена для трех наиболее распространенных строк шаблона, используемых в обзоре общедоступного исходного кода Go.

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

Parse теперь игнорирует точность менее наносекунды в своих входных данных, вместо того, чтобы сообщать об этих цифрах как об ошибке.

Метод Time.MarshalJSON теперь более строго соответствует RFC 3339.

unicode/utf16

Новая функция AppendRune добавляет кодировку UTF-16 данной руны к фрагменту uint16, аналогично utf8.AppendRune.


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