Примечания к выпуску Go 1.20
Введение в 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, теперь эти функции обеспечивают полную возможность
создавать и разбирать значения срезов и строк, не завися от их точного представления.
Спецификация теперь определяет, что значения структур сравниваются по одному полю за раз, учитывая поля в порядке их появления в определении типа структуры, и останавливаясь на первом несовпадении. Ранее спецификация могла быть прочитана так, как будто все поля должны были сравниваться даже после первого несовпадения. Аналогично, спецификация теперь определяет, что значения массивов сравниваются по одному элементу за раз, в порядке возрастания индексов. В обоих случаях это изменение влияет на необходимость возникновения паники при некоторых сравнениях. Существующие программы остаются неизменными: новая формулировка спецификации описывает то, что реализации всегда делали.
Сравниваемые типы (такие как обычные интерфейсы)
теперь могут удовлетворять ограничениям comparable, даже если аргументы типа
не являются строго сравнимыми (сравнение может вызвать панику во время выполнения).
Это позволяет создавать экземпляры типа параметра, ограниченного comparable
(например, тип параметра для пользовательского ключа дженерик-карты) с аргументом типа,
который не является строго сравнимым, таким как интерфейсный тип или составной тип,
содержащий интерфейсный тип.
Платформы
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 build больше не проверяет их наличие,
и дистрибутив Go больше не поставляется с ними.
Вместо этого пакеты стандартной библиотеки собираются по мере необходимости
и кэшируются в кэше сборки, точно так же, как и пакеты вне GOROOT.
Это изменение уменьшает размер дистрибутива Go и также
избегает проблем с несоответствием инструментария C для пакетов, использующих cgo.
Реализация команды go test -json
была улучшена для повышения надежности.
Программы, которые запускают go test -json,
не требуют никаких обновлений.
Программы, которые напрямую вызывают go tool test2json,
теперь должны запускать тестовый бинарный файл с флагом -v=test2json
(например, go test -v=test2json
или ./pkg.test -test.v=test2json)
вместо простого -v.
Связанное изменение в go test -json
заключается в добавлении события с Action, установленным в start,
в начале выполнения каждой тестовой программы.
При запуске нескольких тестов с использованием команды go,
эти события запуска гарантированно будут выдаваться в том же порядке,
что и пакеты, указанные в командной строке.
Команда go теперь определяет теги сборки для функций архитектуры, такие как amd64.v2,
чтобы позволить выбирать файл реализации пакета на основе наличия или отсутствия определённой архитектурной функции.
См. go help buildconstraint для получения подробной информации.
Подкоманды 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 больше не устанавливает библиотеки для
пакетов, не являющихся main, в GOPATH/pkg,
и go list больше не отображает поле Target
для таких пакетов. (В режиме модулей скомпилированные пакеты хранятся в
кэше сборки
только, но ошибка приводила к тому,
что цели установки GOPATH внезапно оставались активными.)
Команды go build, go install,
и другие команды, связанные со сборкой, теперь поддерживают флаг -pgo, который включает
профайлинг-ориентированную оптимизацию, подробное описание которой содержится в
разделе Компилятор ниже.
Флаг -pgo указывает путь к файлу профиля.
Указание -pgo=auto заставляет команду go искать файл с именем default.pgo
в директории главного пакета и использовать его, если он существует.
Этот режим требует указания одного главного пакета в командной строке, но мы планируем снять это ограничение в будущем релизе.
Указание -pgo=off отключает профайлинг-ориентированную оптимизацию.
Команды go build, go install,
и другие команды, связанные со сборкой, теперь поддерживают флаг -cover,
который собирает указанный объект с инструментированием для измерения покрытия кода.
Это подробно описано в разделе Cover ниже.
go version
Команда go version -m теперь поддерживает чтение большего количества типов двоичных файлов Go, в том числе, Windows DLL, собранные с помощью 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, так и для недженериковых сборок,
а также для кроссплатформенных сборок.
На Windows пакеты net и os/user никогда не использовали cgo.
На других системах сборки с отключенным cgo будут использовать чисто Go-версию этих пакетов.
В результате, на macOS, если Go-код, использующий пакет net, собирается
с флагом -buildmode=c-archive, то для связи полученного архива
в C-программу требуется передавать -lresolv при линковке C-кода.
На macOS детектор гонок (race detector) был переписан так, чтобы он не использовал cgo: программы с включенным детектором гонок могут быть собраны и запущены без Xcode. На Linux и других Unix-системах, а также на Windows, для использования детектора гонок требуется наличие C-инструментария хост-системы.
Cover
Go 1.20 поддерживает сборку профилей покрытия кода для программ (приложений и интеграционных тестов), а не только для модульных тестов.
Чтобы собрать данные о покрытии для программы, соберите её с флагом go
build -cover, а затем запустите полученный
исполняемый файл с установленной переменной окружения GOCOVERDIR,
указывающей на директорию для сохранения профилей покрытия.
См. страницу «coverage for integration tests» для получения информации о том, как начать работу.
Для подробностей о дизайне и реализации см. предложение.
Vet
Улучшенная диагностика захвата переменных цикла вложенным функциями
Инструмент vet теперь сообщает о ссылках на переменные цикла после вызова
T.Parallel()
в теле функций подтестов. Такие ссылки могут наблюдать значение переменной
из другой итерации (что обычно приводит к пропуску тест-кейсов) или к некорректному состоянию
из-за несинхронизированного параллельного доступа.
Инструмент также обнаруживает ошибки ссылок в более широком круге мест. Ранее он учитывал только последнюю инструкцию тела цикла,
но теперь рекурсивно проверяет последние инструкции внутри инструкций if, switch и select.
Новый диагностический инструмент для некорректных форматов времени
Инструмент vet теперь сообщает об использовании формата времени 2006-02-01 (yyyy-dd-mm)
с Time.Format и
time.Parse.
Этот формат не встречается в общепринятых стандартных форматах дат, но часто
используется по ошибке при попытке использовать формат ISO 8601
(yyyy-mm-dd).
Среда выполнения
Некоторые внутренние структуры данных сборщика мусора были переработаны для увеличения эффективности по памяти и CPU. Это изменение снижает накладные расходы на память и улучшает общую производительность 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 build,
как упоминалось выше.
Go 1.20 использует PGO для более агрессивной вставки функций в горячие места вызовов.
Бенчмарки для представительного набора программ на Go показывают, что включение
оптимизации вставки на основе профайлинга улучшает производительность примерно на 3–4%.
См. руководство пользователя по PGO для подробной документации.
В будущих релизах планируется добавить ещё больше профайлинг-ориентированных оптимизаций.
Обратите внимание, что профайлинг-ориентированная оптимизация находится на этапе предварительной поддержки,
поэтому рекомендуется использовать её с соответствующей осторожностью.
Компилятор Go 1.20 обновил свой фронтенд для использования нового способа работы с внутренними данными компилятора, что исправляет несколько проблем с дженериками и позволяет объявлять типы внутри дженерик-функций и методов.
Компилятор теперь отклоняет анонимные циклы интерфейсов с ошибкой компилятора по умолчанию. Они возникают при сложном использовании встроенных интерфейсов и всегда имели скрытые проблемы корректности, однако нет никаких доказательств того, что они реально используются на практике. Предполагая отсутствие сообщений от пользователей, негативно затронутых этим изменением, мы планируем обновить спецификацию языка для Go 1.22, чтобы официально запретить их, чтобы авторы инструментов могли прекратить поддержку таких конструкций.
В Go 1.18 и 1.19 наблюдалась регрессия скорости сборки, в основном из-за добавления поддержки дженериков и последующей работы. Go 1.20 улучшает скорость сборки до 10%, возвращая её к уровню Go 1.17. Относительно Go 1.19, производительность сгенерированного кода также в целом немного улучшена.
Линковщик
В Linux линковщик теперь выбирает динамический интерпретатор для glibc
или musl во время компоновки.
В Windows линковщик Go теперь поддерживает современные LLVM-основанные C-инструменты.
Go 1.20 использует префиксы go: и type: для символов, генерируемых компилятором,
вместо go. и type..
Это предотвращает путаницу с пользовательскими пакетами, имена которых начинаются с go..
Пакет debug/gosym понимает
это новое соглашение об именовании для бинарных файлов, собранных с Go 1.20 и новее.
Bootstrap
При сборке релиза Go из исходных кодов, если переменная окружения GOROOT_BOOTSTRAP не установлена, предыдущие версии Go искали инструментарий для bootstrap в директории $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 при bootstrap Go 1.20. Go 1.20 действительно требует релиз Go 1.17 для bootstrap, но мы поняли, что следует использовать последний патч-релиз инструментария bootstrap, поэтому теперь требуется Go 1.17.13. Go 1.20 ищет $HOME/go1.17.13 или $HOME/sdk/go1.17.13, прежде чем переходить к $HOME/go1.4 (для поддержки систем, где жестко задан путь $HOME/go1.4, но установлен более новый инструментарий Go). В будущем мы планируем перемещать инструментарий bootstrap вперед примерно раз в год, и в частности ожидается, что Go 1.22 будет требовать финальный патч-релиз Go 1.20 для bootstrap.
Стандартная библиотека
Новый пакет crypto/ecdh
Go 1.20 добавляет новый пакет crypto/ecdh для предоставления явной поддержки обмена ключами по схеме Эллиптические кривые Диффи-Хеллмана (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, позволяют устанавливать таймауты чтения и записи на уровне запроса. Например:
<code>func RequestHandler(w ResponseWriter, r *Request) {
rc := http.NewResponseController(w)
rc.SetWriteDeadline(time.Time{}) // отключить Server.WriteTimeout при отправке большого ответа
io.Copy(w, bigData)
}
</code>
Новая функция перезаписи ReverseProxy
Прокси-сервер пересылки httputil.ReverseProxy включает новую функцию обратного вызова Rewrite, которая заменяет предыдущую функцию Director.
Хук Rewrite принимает параметр
ProxyRequest,
который включает как входящий запрос, полученный прокси, так и исходящий
запрос, который будет отправлен.
В отличие от хуков Director, которые работают только с исходящим запросом,
это позволяет хукам Rewrite избегать определённых сценариев, когда
злонамеренный входящий запрос может привести к удалению заголовков, добавленных хуком,
перед пересылкой.
См. issue #50580.
Метод
ProxyRequest.SetURL
направляет исходящий запрос в указанное место назначения
и отменяет действие функции NewSingleHostReverseProxy.
В отличие от NewSingleHostReverseProxy, метод SetURL
также устанавливает заголовок Host исходящего запроса.
Метод
ProxyRequest.SetXForwarded
устанавливает заголовки X-Forwarded-For, X-Forwarded-Host,
и X-Forwarded-Proto исходящего запроса.
При использовании Rewrite эти заголовки не добавляются по умолчанию.
Пример хука Rewrite, использующего эти функции:
<code>proxyHandler := &httputil.ReverseProxy{
Rewrite: func(r *httputil.ProxyRequest) {
r.SetURL(outboundURL) // Переслать запрос на outboundURL.
r.SetXForwarded() // Установить заголовки X-Forwarded-*.
r.Out.Header.Set("X-Additional-Header", "header set by the proxy")
},
}
</code>
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
При использовании поддерживаемых кривых, все операции теперь реализованы с постоянным временем. Это привело к увеличению времени CPU между 5% и 30%, в основном affecting 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 теперь использует новое, более безопасное, постоянное по времени выполнения backend. Это вызывает увеличение времени выполнения CPU для операций расшифровки примерно на 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
теперь возвращают ошибку.
Для использования с системами LoongArch определены дополнительные константы R_LARCH_*.
Для использования с PPC64 ELFv2 релокациями определены дополнительные константы R_PPC64_*.
Исправлено значение константы R_PPC64_SECTOFF_LO_DS, с 61 на 62.
debug/gosym
Из-за изменения конвенций именования символов Go, инструменты, обрабатывающие двоичные файлы Go, должны использовать пакет debug/gosym версии Go 1.20 для прозрачной обработки как старых, так и новых двоичных файлов.
debug/pe
Для использования с системами RISC-V определены дополнительные константы IMAGE_FILE_MACHINE_RISCV*.
encoding/binary
Функции ReadVarint и
ReadUvarint
теперь возвращают io.ErrUnexpectedEOF после чтения частичного значения,
вместо io.EOF.
encoding/xml
Новый метод Encoder.Close может использоваться для проверки наличия незакрытых элементов после завершения кодирования.
Декодер теперь отклоняет имена элементов и атрибутов, содержащих более одной двоеточия, например <a:b:c>,
а также пространства имен, которые разрешаются в пустую строку, например xmlns:a="".
Декодер теперь отклоняет элементы, использующие разные префиксы пространств имен в открывающем и закрывающем теге, даже если эти префиксы обозначают одно и то же пространство имен.
errors
Новая функция Join возвращает ошибку, обёртывающую список ошибок.
fmt
Функция Errorf поддерживает несколько вхождений
форматного спецификатора %w, возвращая ошибку, которая раскрывается в список всех аргументов, переданных в %w.
Новая функция FormatString восстанавливает
директиву форматирования, соответствующую State,
что может быть полезно в реализациях Formatter.
go/ast
Новое поле RangeStmt.Range
записывает позицию ключевого слова range в инструкции цикла.
Новые поля File.FileStart
и File.FileEnd
записывают позиции начала и конца всего исходного файла.
go/token
Новый метод FileSet.RemoveFile
удаляет файл из FileSet.
Долгосрочные программы могут использовать это для освобождения памяти, связанной с файлами, которые больше не требуются.
go/types
Новая функция Satisfies сообщает,
удовлетворяет ли тип ограничению.
Это изменение согласуется с новой семантикой языка,
которая отличает удовлетворение ограничения от реализации интерфейса.
html/template
Go 1.20.3 и более поздние версии
запрещают действия в литералах шаблонов ECMAScript 6.
Это поведение можно отменить с помощью параметра GODEBUG=jstmpllitinterp=1.
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 в своей среде.
Функция верхнего уровня Read устарела.
В большинстве случаев лучше использовать crypto/rand.Read.
mime
Функция ParseMediaType теперь разрешает дублирующиеся имена параметров,
при условии, что значения этих имен совпадают.
mime/multipart
Методы типа Reader теперь оборачивают ошибки,
возвращаемые базовым io.Reader.
Начиная с Go 1.19.8, данный пакет устанавливает ограничения на размер
обрабатываемых MIME-данных для защиты от вредоносных входных данных.
Reader.NextPart и Reader.NextRawPart ограничивают
количество заголовков в части до 10000, а Reader.ReadForm ограничивает
общее количество заголовков во всех FileHeaders до 10000.
Эти ограничения могут быть изменены с помощью параметра GODEBUG=multipartmaxheaders.
Reader.ReadForm дополнительно ограничивает количество частей в форме до 1000.
Это ограничение может быть изменено с помощью параметра GODEBUG=multipartmaxparts.
net
Функция LookupCNAME
теперь последовательно возвращает содержимое
записи CNAME, если таковая существует. Ранее на системах Unix и
при использовании чистого Go-резолвера, LookupCNAME возвращала ошибку,
если запись CNAME ссылалась на имя, не имеющее записей A,
AAAA или CNAME. Это изменение модифицирует
поведение LookupCNAME, чтобы оно соответствовало предыдущему поведению в Windows,
позволяя LookupCNAME успешно завершаться, когда существует
запись CNAME.
Interface.Flags теперь включает новый флаг FlagRunning,
указывающий на операционно активный интерфейс. Интерфейс, который настроен административно,
но не активен (например, из-за отсутствия подключения к сети),
будет иметь установленный флаг FlagUp, но не FlagRunning.
Новое поле Dialer.ControlContext содержит функцию обратного вызова,
аналогично существующему полю Dialer.Control, но дополнительно
принимающей контекст соединения в качестве параметра.
Поле Control игнорируется, если ControlContext не равно nil.
Go DNS-резолвер распознаёт параметр резолвера trust-ad.
Когда в файле resolv.conf установлен параметр options 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 «name =value» теперь принимается как установка cookie «name».
Cookie с пустым полем Expires теперь считается действительным.
Cookie.Valid проверяет поле Expires только тогда, когда оно установлено.
net/netip
Новые функции IPv6LinkLocalAllRouters и IPv6Loopback являются эквивалентами net.IPv6loopback и net.IPv6linklocalallrouters в пакете net/netip.
os
В Windows имя NUL больше не рассматривается как специальный случай в функциях Mkdir и Stat.
В Windows File.Stat теперь использует дескриптор файла для получения атрибутов, когда файл является каталогом.
Ранее использовался путь, переданный в Open, который мог больше не соответствовать файлу, представленному дескриптором, если файл был перемещён или заменён.
Это изменение изменяет поведение Open, чтобы открывать каталоги без флага доступа FILE_SHARE_DELETE, что соответствует поведению обычных файлов.
В Windows File.Seek теперь поддерживает поиск в начале каталога.
os/exec
Новые поля Cmd Cancel и WaitDelay задают поведение Cmd при отмене связанного Context или при завершении процесса с открытыми дочерними процессами I/O-каналами.
path/filepath
Новая ошибка SkipAll прерывает Walk немедленно, но успешно.
Новая функция IsLocal сообщает, является ли путь лексически локальным по отношению к каталогу.
Например, если IsLocal(p) возвращает true, то Open(p) будет ссылаться на файл, который лексически находится внутри поддерева, корнем которого является текущий каталог.
reflect
Новые методы Value.Comparable и Value.Equal могут использоваться для сравнения двух значений Value на равенство.
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,
парсер возвращает syntax.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
Фоновый очистщик сборщика мусора теперь режеyield, что приводит к гораздо меньшему количеству лишних событий в трассировках выполнения.
strings
Новые функции
CutPrefix и
CutSuffix
похожи на TrimPrefix
и TrimSuffix,
но также сообщают, был ли обрезан строковый литерал.
sync
Новые методы Map Swap,
CompareAndSwap и
CompareAndDelete
позволяют атомически обновлять существующие записи в карте.
syscall
В FreeBSD удалены shim'ы совместимости, необходимые для FreeBSD 11 и более ранних версий.
В Linux определены дополнительные константы CLONE_*
для использования с полем SysProcAttr.Cloneflags.
В Linux новые поля SysProcAttr.CgroupFD
и SysProcAttr.UseCgroupFD
предоставляют способ поместить дочерний процесс в определённую cgroup.
testing
Новый метод B.Elapsed
сообщает текущее прошедшее время теста, что может быть полезно для вычисления частоты и её отчета с помощью ReportMetric.
Вызов T.Run
из функции, переданной в T.Cleanup,
никогда не был корректно определён и теперь приводит к панике.
time
Новые константы формата времени DateTime,
DateOnly и
TimeOnly
предоставляют имена для трёх наиболее часто используемых строк формата, встречающихся в обзоре публичного Go-кода.
Новый метод Time.Compare
сравнивает два момента времени.
Parse
теперь игнорирует субнаносекундную точность во входных данных,
вместо того чтобы сообщать об этих цифрах как об ошибке.
Метод Time.MarshalJSON
теперь более строго соблюдает требования RFC 3339.
unicode/utf16
Новая функция AppendRune
добавляет кодировку UTF-16 заданного rune в срез uint16,
аналогично utf8.AppendRune.