Примечания к выпуску Go 1.18
Введение в Go 1.18
Последний выпуск Go, версия 1.18, представляет собой значительное обновление, включающее изменения в языке, реализацию инструментария, среды выполнения и библиотек. Go 1.18 выходит через семь месяцев после Go 1.17. Как и всегда, выпуск сохраняет обещание совместимости Go 1. Ожидается, что почти все программы на Go продолжат компилироваться и выполняться так же, как и раньше.
Изменения в языке
Дженерики
Go 1.18 включает реализацию дженерик-функций, описанных в предложении о параметрах типов. Это включает в себя крупные — но полностью обратно совместимые — изменения в языке.
Эти новые языковые изменения потребовали создания большого количества нового кода, который ещё не проходил значительного тестирования в промышленных условиях. Это произойдёт только тогда, когда больше людей начнут писать и использовать дженерик-код. Мы считаем, что эта функция хорошо реализована и имеет высокое качество. Однако, в отличие от большинства аспектов Go, мы не можем подтвердить это практическим опытом. Поэтому, хотя мы призываем использовать дженерики там, где это уместно, пожалуйста, проявляйте соответствующую осторожность при внедрении дженерик-кода в продакшен.
Хотя мы считаем, что новые языковые возможности хорошо спроектированы и ясно описаны, возможно, мы допустили ошибки. Мы хотим подчеркнуть, что гарантия совместимости Go 1 говорит о том, что «Если будет необходимо устранить несоответствие или неполноту в спецификации, решение проблемы может повлиять на смысл или законность существующих программ. Мы оставляем за собой право устранить такие проблемы, включая обновление реализаций». Также говорится: «Если компилятор или библиотека имеет ошибку, нарушающую спецификацию, программа, зависящая от неправильного поведения, может сломаться, если ошибка будет исправлена. Мы оставляем за собой право исправлять такие ошибки». Другими словами, возможно, будет существовать код с использованием дженериков, который будет работать с выпуском 1.18, но сломается в более поздних релизах. Мы не планируем и не ожидаем вносить такие изменения. Однако, необходимость внесения подобных изменений в будущих выпусках может возникнуть по причинам, которые мы не можем предвидеть сегодня. Мы минимизируем возможное нарушение, но не можем гарантировать, что оно будет равно нулю.
Ниже приведён список наиболее заметных изменений. Для более полного обзора см. предложение. Для подробностей см. спецификацию языка.
- Синтаксис для функций и объявлений типов теперь принимает параметры типов.
- Параметризованные функции и типы могут быть инстанцированы путём добавления списка аргументов типов в квадратных скобках после них.
- В набор операторов и пунктуации добавлен новый токен
~. - Синтаксис для
интерфейсов
теперь позволяет встраивать произвольные типы (не только имена типов интерфейсов)
а также объединения и элементы типа
~T. Такие интерфейсы могут использоваться только как ограничения типов. Интерфейс теперь определяет набор типов, а также набор методов. - Новый
предварительно объявленный идентификатор
anyявляется псевдонимом для пустого интерфейса. Его можно использовать вместоinterface{}. - Новый
предварительно объявленный идентификатор
comparable— это интерфейс, обозначающий набор всех типов, которые можно сравнивать с помощью==или!=. Он может использоваться только как (или встроенный в) ограничение типа.
Существует три экспериментальных пакета, использующих дженерики, которые могут быть полезны. Эти пакеты находятся в репозитории x/exp; их API не защищено гарантией Go 1 и может измениться по мере того, как мы получим больше опыта с дженериками.
golang.org/x/exp/constraints
Ограничения, полезные для дженерик-кода, такие как
constraints.Ordered.
golang.org/x/exp/slices
Коллекция дженерик-функций, работающих со срезами любого типа элемента.
golang.org/x/exp/maps
Коллекция дженерик-функций, работающих с картами любого типа ключа или элемента.
Текущая реализация дженериков имеет следующие известные ограничения:
- Компилятор Go не может обрабатывать объявления типов внутри дженерик-функций или методов. Надеемся предоставить поддержку этой функции в будущем релизе.
-
Компилятор Go не принимает аргументы типа параметра типа с предварительно объявленными функциями
real,imagиcomplex. Надеемся убрать это ограничение в будущем релизе. -
Компилятор Go поддерживает вызов метода
mна значенииxтипа параметраPтолько в том случае, еслиmявно объявлен в интерфейсе ограниченияP. Аналогично, значения методовx.mи выражения методовP.mтакже поддерживаются только в том случае, еслиmявно объявлен вP, даже еслиmможет быть в наборе методовPпо причине того, что все типы вPреализуютm. Надеемся убрать это ограничение в будущем релизе. -
Компилятор Go не поддерживает доступ к полю структуры
x.f, гдеxимеет тип параметра, даже если все типы в наборе типов параметра имеют полеf. Мы можем убрать это ограничение в будущем релизе. - Встраивание типа параметра или указателя на тип параметра как безымянного поля в структуре не допускается. Аналогично, встраивание типа параметра в интерфейс также не допускается. Непонятно, будет ли это когда-либо разрешено.
- Элемент объединения с более чем одним термом не может содержать интерфейсный тип с непустым набором методов. Непонятно, будет ли это когда-либо разрешено.
Дженерики также представляют собой крупное изменение для экосистемы Go. Хотя мы обновили несколько основных инструментов с поддержкой дженериков, ещё многое предстоит сделать. Время потребуется для того, чтобы остальные инструменты, документация и библиотеки догнали изменения в языке.
Исправления ошибок
Компилятор Go 1.18 теперь корректно сообщает об ошибках
declared but not used для переменных, которые присваиваются внутри литерала функции, но никогда не используются. До Go 1.18
компилятор не сообщал об ошибке в таких случаях. Это исправляет давно существующую проблему компилятора
#8560. В результате этого изменения,
(возможно, некорректные) программы могут больше не компилироваться. Необходимое исправление
простое: исправьте программу, если она действительно была некорректной, или используйте подозрительную
переменную, например, присвойте её пустому идентификатору _.
Поскольку go vet всегда указывал на эту ошибку, количество затронутых
программ, вероятно, очень мало.
Компилятор Go 1.18 теперь сообщает об переполнении при передаче константного выражения rune, такого как '1' << 32, в качестве аргумента в предварительно объявленные функции print и println, что согласуется с поведением пользовательских функций. До Go 1.18 компилятор не сообщал об ошибке в таких случаях, но без ошибок принимал такие константные аргументы, если они помещались в int64. В результате этого изменения (возможно, некорректные) программы могут больше не компилироваться. Необходимое исправление простое: исправьте программу, если она действительно была некорректной, или явно преобразуйте проблемный аргумент к правильному типу. Поскольку go vet всегда указывал на эту ошибку, количество затронутых программ, вероятно, очень мало.
Порты
AMD64
Go 1.18 вводит новую переменную среды GOAMD64, которая выбирает минимальную целевую версию архитектуры AMD64 во время компиляции. Допустимые значения: v1, v2, v3 или v4. Каждый более высокий уровень требует и использует дополнительные возможности процессора. Подробное описание можно найти здесь.
Переменная среды GOAMD64 по умолчанию имеет значение v1.
RISC-V
64-битная архитектура RISC-V в Linux (порт linux/riscv64) теперь поддерживает режимы сборки c-archive и c-shared.
Linux
Go 1.18 требует ядро Linux версии 2.6.32 или более поздней.
Windows
Порты windows/arm и windows/arm64 теперь поддерживают некооперативное прекращение выполнения (non-cooperative preemption), что делает эту возможность доступной для всех четырех портов Windows, что, надеемся, поможет устранить тонкие ошибки, возникающие при вызове Win32-функций, которые блокируются на длительное время.
iOS
В iOS (порт ios/arm64) и симуляторе iOS, работающем на macOS на базе AMD64 (порт ios/amd64), Go 1.18 теперь требует iOS 12 или более поздней версии; поддержка предыдущих версий прекращена.
FreeBSD
Go 1.18 — последний релиз, поддерживаемый на FreeBSD 11.x, который уже достиг конца срока службы. Go 1.19 будет требовать FreeBSD 12.2+ или FreeBSD 13.0+. FreeBSD 13.0+ будет требовать ядро с включённой опцией COMPAT_FREEBSD12 (по умолчанию она включена).
Инструменты
Fuzzing
Go 1.18 включает реализацию fuzzing согласно предложению по fuzzing.
См. страницу fuzzing, чтобы начать работу.
Обратите внимание, что fuzzing может потреблять много памяти и может влиять на производительность вашей машины во время выполнения. Также учтите, что движок fuzzing записывает значения, расширяющие покрытие тестов, в каталог кэша fuzz внутри $GOCACHE/fuzz во время выполнения. В настоящее время нет ограничений на количество файлов или общего количества байтов, которые могут быть записаны в кэш fuzz, поэтому он может занимать большое количество места (возможно, несколько ГБ).
Команда go
go get
Команда go get больше не собирает и не устанавливает пакеты в режиме, осведомленном о модулях. Теперь go get предназначена исключительно для изменения зависимостей в go.mod. По сути, флаг -d всегда включен. Чтобы установить последнюю версию исполняемого файла вне контекста текущего модуля, используйте go install example.com/cmd@latest. Вместо latest может использоваться любая версия. Эта форма go install была добавлена в Go 1.16, поэтому проекты, поддерживающие более старые версии, могут потребовать указания инструкций по установке как для go install, так и для go get. Теперь go get сообщает об ошибке при использовании вне модуля, поскольку нет файла go.mod для обновления. В режиме GOPATH (с GO111MODULE=off), go get продолжает собирать и устанавливать пакеты, как и прежде.
Автоматическое обновление go.mod и go.sum
Подкоманды go mod graph,
go mod vendor,
go mod verify и
go mod why больше не обновляют файлы go.mod и
go.sum автоматически.
(Обновить эти файлы можно вручную с помощью команд go get,
go mod tidy или
go mod download.)
go version
Команда go теперь встраивает информацию о системе контроля версий в
бинарные файлы. В них включается текущая проверенная ревизия, время коммита и
флаг, указывающий, есть ли отредактированные или неотслеживаемые файлы. Информация о системе контроля версий встраивается, если команда go вызывается в директории, находящейся в репозитории Git, Mercurial, Fossil или Bazaar, и пакет main и содержащий его основной модуль находятся в одном и том же репозитории. Эту информацию можно исключить с помощью флага
-buildvcs=false.
Кроме того, команда go встраивает информацию о сборке,
включая теги сборки и инструментов (устанавливаемые с помощью -tags), флаги компилятора,
асsembler и linker (например, -gcflags), включён ли cgo,
и если да, то значения переменных окружения cgo
(например, CGO_CFLAGS).
Информация о системе контроля версий и сборке может быть прочитана вместе с информацией о модулях с помощью
go version -m file или
runtime/debug.ReadBuildInfo (для запущенного в данный момент бинарного файла)
или нового пакета debug/buildinfo.
Формат данных встроенной информации о сборке может изменяться с каждым новым релизом go,
поэтому более старая версия go может не справиться с информацией о сборке,
созданной с помощью более новой версии go.
Чтобы прочитать информацию о версии из бинарного файла, собранного с помощью go 1.18,
используйте команду go version и пакет debug/buildinfo из go 1.18+.
go mod download
Если в файле go.mod основного модуля указано
go 1.17
или выше, команда go mod download без аргументов теперь загружает исходный код только для модулей,
явно требуемых в файле go.mod основного модуля.
(В модуле версии go 1.17 или выше этот набор уже включает все зависимости, необходимые для сборки пакетов и тестов в основном модуле.)
Чтобы загрузить также исходный код для транзитивных зависимостей, используйте
go mod download all.
go mod vendor
Подкоманда go mod vendor теперь
поддерживает флаг -o для установки директории вывода.
(Другие команды go по-прежнему читают из директории vendor
в корне модуля при загрузке пакетов с флагом -mod=vendor, поэтому основное применение этого флага — для сторонних инструментов, которым требуется собрать исходный код пакетов.)
go mod tidy
Команда go mod tidy теперь сохраняет
дополнительные контрольные суммы в файле go.sum для модулей, исходный код которых необходим для проверки того, что каждый импортируемый пакет предоставляется только одним модулем в
списке сборки. Поскольку это условие редко встречается и отсутствие его применения приводит к ошибке сборки, это изменение не зависит от версии go в файле go.mod основного модуля.
go work
Команда go теперь поддерживает режим «Рабочей области» (workspace). Если файл go.work находится в рабочем каталоге или в родительском каталоге, либо он указан с помощью переменной окружения GOWORK, команда go будет работать в режиме рабочей области. В этом режиме файл go.work будет использоваться для определения набора основных модулей, используемых в качестве корней для разрешения модулей, вместо использования обычного файла go.mod, который указывает единственный основной модуль. Дополнительную информацию см. в документации по go work.
go build -asan
Команда go build и связанные с ней команды теперь поддерживают флаг -asan, который обеспечивает взаимодействие с кодом на C (или C++), скомпилированным с использованием sanitizer адресов (параметр компилятора C -fsanitize=address).
go test
Команда go теперь поддерживает дополнительные параметры командной строки для нового fuzzing-поддержки, описанной выше:
go testподдерживает параметры-fuzz,-fuzztimeи-fuzzminimizetime. Документацию по этим параметрам см. вgo help testflag.go cleanподдерживает параметр-fuzzcache. Документацию см. вgo help clean.
//go:build линии
Go 1.17 ввёл //go:build линии как более читаемый способ записи ограничений сборки вместо // +build линий.
Начиная с Go 1.17, gofmt добавляет //go:build линии, чтобы соответствовать существующим +build линиям, и поддерживает их синхронизацию, в то время как go vet выявляет случаи, когда они не синхронизированы.
Поскольку выпуск Go 1.18 означает завершение поддержки Go 1.16, все поддерживаемые версии Go теперь понимают //go:build линии.
В Go 1.18 команда go fix теперь удаляет устаревшие // +build линии в модулях, объявляющих go 1.18 или более позднюю версию в их go.mod файлах.
Для получения дополнительной информации см. go.dev/design/draft-gobuild.
Gofmt
gofmt теперь читает и форматирует входные файлы параллельно, с ограничением памяти, пропорциональным GOMAXPROCS. На машине с несколькими процессорами gofmt теперь должен быть значительно быстрее.
Vet
Обновления для дженериков
Инструмент vet обновлён для поддержки дженерик-кода. В большинстве случаев он сообщает об ошибке в дженерик-коде, если бы он сообщил об ошибке в эквивалентном недженерик-коде после подстановки типов параметров с типом из их набора типов.
Например, vet сообщает об ошибке форматирования в
<code>func Print[T ~int|~string](t T) {
fmt.Printf("%d", t)
}
</code>
потому что он сообщал бы об ошибке форматирования в недженерик-эквиваленте Print[string]:
<code>func PrintString(x string) {
fmt.Printf("%d", x)
}
</code>
Улучшения точности существующих проверок
Проверяющие инструменты cmd/vet copylock, printf,
sortslice, testinggoroutine и tests
получили умеренные улучшения точности для обработки дополнительных паттернов кода.
Это может привести к появлению новых сообщений об ошибках в существующих пакетах. Например, проверяющий инструмент printf теперь отслеживает строки форматирования, созданные путём конкатенации строковых констант. Таким образом, vet сообщит об ошибке в:
<code> // Директива форматирования fmt.Printf %d передаётся в Println.
fmt.Println("%d"+` ≡ x (mod 2)`+"\n", x%2)
</code>
Среда выполнения
Сборщик мусора теперь учитывает источники работы сборщика мусора, не связанные с кучей
(например, сканирование стека) при определении частоты его запуска. В результате,
накладные расходы сборщика мусора становятся более предсказуемыми, когда эти источники
имеют значительное влияние. Для большинства приложений эти изменения будут незначительными;
однако некоторые приложения на Go теперь могут использовать меньше памяти и тратить больше времени
на сборку мусора, или наоборот, чем раньше. Предполагаемое решение — настроить
GOGC при необходимости.
Среда выполнения теперь более эффективно возвращает память операционной системе и была настроена для более агрессивной работы в результате.
Go 1.17 в целом улучшил форматирование аргументов в трассировке стека,
но мог выводить неточные значения для аргументов, переданных через регистры.
Это улучшено в Go 1.18 путем вывода знака вопроса (?)
после каждого значения, которое может быть неточным.
Встроенная функция append теперь использует немного другую формулу
при принятии решения о том, насколько увеличивать срез при необходимости выделения нового
базового массива. Новая формула менее подвержена внезапным переходам в поведении выделения.
Компилятор
Go 1.17 реализовал новый способ передачи
аргументов функций и результатов с использованием регистров вместо стека
на 64-битной архитектуре x86 на выбранных операционных системах.
Go 1.18 расширяет поддерживаемые платформы, включая 64-битный ARM (GOARCH=arm64),
big-endian и little-endian 64-битный PowerPC (GOARCH=ppc64, ppc64le),
а также 64-битную архитектуру x86 (GOARCH=amd64)
на всех операционных системах.
На 64-битных ARM и 64-битных PowerPC системах бенчмарки показывают
типичные улучшения производительности на 10% или более.
Как упоминалось в заметках о выпуске Go 1.17, это изменение не влияет на функциональность любого безопасного кода на Go и предназначено для того, чтобы не иметь никакого влияния на большинство ассемблерных кодов. См. заметки о выпуске Go 1.17 для получения дополнительной информации.
Компилятор теперь может встраивать функции, содержащие циклы range или помеченные циклы for.
Новая опция компилятора -asan поддерживает новую опцию
команды go -asan.
Поскольку проверяющий типов компилятора был полностью заменён для поддержки дженериков, некоторые сообщения об ошибках теперь могут использовать другую формулировку, чем раньше. В некоторых случаях, предшествующие сообщения об ошибках до Go 1.18 предоставляли больше деталей или были сформулированы более полезным образом. Мы планируем устранить эти случаи в Go 1.19.
Из-за изменений в компиляторе, связанных с поддержкой дженериков, время компиляции Go 1.18 может быть примерно на 15% медленнее, чем у Go 1.17. Время выполнения скомпилированного кода не затрагивается. Мы планируем улучшить скорость компилятора в будущих релизах.
Линкер
Линкер теперь выдает гораздо меньше пересылки.
В результате, большинство кодовых баз будут связываться быстрее, требовать меньше памяти для связи
и генерировать более мелкие бинарные файлы.
Инструменты, обрабатывающие бинарные файлы Go, должны использовать пакет debug/gosym Go 1.18
для прозрачной обработки как старых, так и новых бинарных файлов.
Новая опция линкера -asan поддерживает новую опцию
команды go -asan.
Bootstrap
При сборке релиза Go из исходников и если GOROOT_BOOTSTRAP
не установлен, предыдущие версии Go искали инструментарий для запуска Go 1.4 или более поздней версии
в каталоге $HOME/go1.4 (%HOMEDRIVE%%HOMEPATH%\go1.4 на Windows).
Теперь Go сначала ищет $HOME/go1.17 или $HOME/sdk/go1.17
перед тем, как переключаться на $HOME/go1.4.
Мы планируем, чтобы Go 1.19 требовал Go 1.17 или более поздней версии для запуска,
и это изменение должно сделать переход более плавным.
Для получения дополнительной информации см. go.dev/issue/44505.
Стандартная библиотека
Новый пакет debug/buildinfo
Новый пакет debug/buildinfo
обеспечивает доступ к версиям модулей, информации о системе контроля версий и флагах сборки, встроенным в исполняемые файлы, созданные командой go.
Та же информация также доступна через
runtime/debug.ReadBuildInfo
для текущего выполняющегося двоичного файла и через команду go
version -m в командной строке.
Новый пакет net/netip
Новый пакет net/netip
определяет новый тип IP-адреса, Addr.
По сравнению с существующим типом
net.IP, тип netip.Addr занимает меньше
памяти, является неизменяемым (immutable) и сравнимым, поэтому поддерживает оператор ==
и может использоваться в качестве ключа в карте.
В дополнение к типу Addr, пакет определяет
AddrPort, представляющий
IP-адрес и порт, а также
Prefix, представляющий
CIDR-префикс сети.
Пакет также определяет несколько функций для создания и анализа
этих новых типов:
AddrFrom4,
AddrFrom16,
AddrFromSlice,
AddrPortFrom,
IPv4Unspecified,
IPv6LinkLocalAllNodes,
IPv6Unspecified,
MustParseAddr,
MustParseAddrPort,
MustParsePrefix,
ParseAddr,
ParseAddrPort,
ParsePrefix,
PrefixFrom.
Пакет net теперь включает новые
методы, параллельные существующим методам, но возвращающие
netip.AddrPort вместо более тяжеловесных типов
net.IP или
*net.UDPAddr:
Resolver.LookupNetIP,
UDPConn.ReadFromUDPAddrPort,
UDPConn.ReadMsgUDPAddrPort,
UDPConn.WriteToUDPAddrPort,
UDPConn.WriteMsgUDPAddrPort.
Новые методы UDPConn поддерживают ввод-вывод без выделения памяти (allocation-free I/O).
Пакет net теперь также включает функции и методы
для преобразования между существующими типами
TCPAddr/UDPAddr
и netip.AddrPort:
TCPAddrFromAddrPort,
UDPAddrFromAddrPort,
TCPAddr.AddrPort,
UDPAddr.AddrPort.
TLS 1.0 и 1.1 по умолчанию отключены на стороне клиента
Если Config.MinVersion
не установлен, теперь по умолчанию используется TLS 1.2 для клиентских подключений. Любая безопасная и актуальная серверная сторона должна поддерживать TLS 1.2, а браузеры требовали его с 2020 года. TLS 1.0 и 1.1 всё ещё поддерживаются при установке
Config.MinVersion в значение VersionTLS10.
Сторонняя серверная настройка по умолчанию остаётся неизменной — TLS 1.0.
По умолчанию, TLS 1.0 можно временно восстановить, установив переменную среды
GODEBUG=tls10default=1.
Эта опция будет удалена в Go 1.19.
Отказ от сертификатов SHA-1
crypto/x509 теперь
отклоняет сертификаты, подписанные с использованием хэш-функции SHA-1. Это не
применяется к самоподписанным корневым сертификатам. Практические атаки против SHA-1
были продемонстрированы с 2017 года, и общедоступные
сертификационные центры больше не выдавали сертификаты SHA-1 с 2015 года.
Это можно временно отменить, установив переменную среды
GODEBUG=x509sha1=1.
Эта опция будет удалена в будущем выпуске.
Незначительные изменения в библиотеке
Как и всегда, в библиотеке были внесены различные незначительные изменения и обновления, сделанные с учётом обещания совместимости Go 1.
bufio
Новый метод Writer.AvailableBuffer
возвращает пустой буфер с возможностью непустой ёмкости для использования
с API, подобными append. После добавления данных, буфер может быть передан
следующему вызову Write и возможно избежать любого копирования.
Методы Reader.Reset и
Writer.Reset
теперь используют размер буфера по умолчанию при вызове на объектах с
nil буфером.
bytes
Новая функция Cut
разбивает []byte по разделителю. Она может заменить и упростить
многие распространённые случаи использования
Index,
IndexByte,
IndexRune,
и SplitN.
Trim, TrimLeft,
и TrimRight теперь не выделяют память и, особенно для
маленьких ASCII cutsets, работают до 10 раз быстрее.
Функция Title теперь устарела. Она не
обрабатывает пунктуацию Юникода и правила капитализации, специфичные для языков, и заменена пакетом
golang.org/x/text/cases.
crypto/elliptic
Реализации кривых P224,
P384, и
P521 теперь поддерживаются кодом, сгенерированным проектами
addchain и
fiat-crypto,
последний из которых основан на формально проверенной модели
арифметических операций. Теперь используются более безопасные полные формулы
и внутренние API. P-224 и P-384 теперь примерно в четыре раза быстрее.
Все конкретные реализации кривых теперь выполняются за постоянное время.
Работа с недопустимыми точками кривой (для которых метод
IsOnCurve возвращает false, и которые никогда не возвращаются
методом Unmarshal или
методом Curve, работающим с допустимой точкой) всегда была
неопределённым поведением, может привести к атакам на восстановление ключа и теперь
не поддерживается новым бэкендом. Если недопустимая точка передаётся методу
P224, P384 или P521, то
этот метод теперь возвращает случайную точку. Поведение может измениться на явную panic
в будущем выпуске.
crypto/tls
Новая метод Conn.NetConn
позволяет получить доступ к базовому
net.Conn.
crypto/x509
Certificate.Verify
теперь использует API платформы для проверки действительности сертификата на macOS и iOS, когда он
вызывается с nil
VerifyOpts.Roots
или при использовании пула корневых сертификатов, возвращаемого функцией
SystemCertPool.
SystemCertPool
теперь доступен в Windows.
В Windows, macOS и iOS, когда
CertPool, возвращаемый функцией
SystemCertPool,
имеет добавленные в него дополнительные сертификаты,
Certificate.Verify
выполняет две проверки: одну с использованием API проверки платформы и системных корневых сертификатов, и вторую с использованием проверки Go и дополнительных корневых сертификатов.
Цепочки, возвращаемые API проверки платформы, будут иметь приоритет.
CertPool.Subjects
устарел. В Windows, macOS и iOS
CertPool, возвращаемый функцией
SystemCertPool,
возвращает пул, который не включает системные корневые сертификаты в срез, возвращаемый методом Subjects, поскольку статический список не может должным образом представлять политики платформы и может вообще не быть доступен через API платформы.
Поддержка подписи сертификатов с использованием алгоритмов подписи, зависящих от хэша MD5 (MD5WithRSA), может быть удалена в Go 1.19.
debug/dwarf
Структуры StructField
и BasicType
теперь имеют поле DataBitOffset, которое хранит значение атрибута
DW_AT_data_bit_offset, если он присутствует.
debug/elf
Константа R_PPC64_RELATIVE
была добавлена.
debug/plan9obj
Метод File.Symbols теперь возвращает новую экспортируемую ошибку ErrNoSymbols если файл не содержит секции символов.
embed
Директива go:embed
теперь может начинаться с all: для включения файлов,
имена которых начинаются с точки или подчеркивания.
go/ast
Согласно предложению
Дополнения в go/ast и go/token для поддержки дженериковых функций и типов
в пакет go/ast добавлены следующие элементы:
- Узлы
FuncTypeиTypeSpecтеперь имеют новое полеTypeParamsдля хранения параметров типа, если они есть. - Новый узел выражения
IndexListExprпредставляет выражения с индексами, содержащими несколько индексов, которые используются для инстанцирования функций и типов с более чем одним явным аргументом типа.
go/constant
Новый метод Kind.String
возвращает человекочитаемое имя для типа получателя.
go/token
Новая константа TILDE
представляет токен ~ согласно предложению
Дополнения к go/ast и go/token для поддержки параметризованных функций и типов
.
go/types
Новое поле Config.GoVersion
устанавливает принимаемую версию языка Go.
Согласно предложению
Дополнения к go/types для поддержки параметров типов
в пакет go/types добавлены следующие изменения:
- Новый тип
TypeParam, фабрическая функцияNewTypeParam, и связанные методы добавлены для представления параметра типа. - Новый тип
TypeParamListхранит список параметров типов. - Новый тип
TypeListхранит список типов. - Новая фабрическая функция
NewSignatureTypeвыделяетSignatureс параметрами типа (получателя или функции). Для доступа к этим параметрам типа типSignatureимеет два новых методаSignature.RecvTypeParamsиSignature.TypeParams. - Типы
Namedимеют четыре новых метода:Named.Originдля получения оригинальных параметризованных типов инстанцированных типов,Named.TypeArgsиNamed.TypeParamsдля получения аргументов типа или параметров типа инстанцированного или параметризованного типа, иNamed.SetTypeParamsдля установки параметров типа (например, при импорте именованного типа, где выделение именованного типа и установка параметров типа не могут быть выполнены одновременно из-за возможных циклов). - Тип
Interfaceимеет четыре новых метода:Interface.IsComparableиInterface.IsMethodSetдля запроса свойств набора типов, определённого интерфейсом, иInterface.MarkImplicitиInterface.IsImplicitдля установки и проверки, является ли интерфейс неявным интерфейсом вокруг литерала ограничения типа. - Новые типы
UnionиTerm, фабричные функцииNewUnionиNewTerm, и связанные методы добавлены для представления наборов типов в интерфейсах. - Новая функция
Instantiateинстанцирует параметризованный тип. - Новая карта
Info.Instancesзаписывает инстанцирования функций и типов через новыйInstanceтип. -
Новый тип
ArgumentErrorи связанные методы добавлены для представления ошибки, связанной с аргументом типа. -
Новый тип
Contextи фабрическая функцияNewContextдобавлены для облегчения совместного использования одинаковых инстанций типов между проверенными пакетами через новое полеConfig.Context.
Предикаты
AssignableTo,
ConvertibleTo,
Implements,
Identical,
IdenticalIgnoreTags и
AssertableTo
теперь также работают с аргументами, которые являются или содержат обобщённые интерфейсы,
то есть интерфейсы, которые могут использоваться только как ограничения типов в коде на Go.
Обратите внимание, что поведение AssignableTo,
ConvertibleTo, Implements и
AssertableTo не определено для аргументов, являющихся
непараметризованными дженериками, а AssertableTo не определён,
если первый аргумент является обобщённым интерфейсом.
html/template
Внутри конвейера range новая команда
{{break}} завершает цикл преждевременно, а новая команда
{{continue}} немедленно начинает следующую итерацию цикла.
Функция and больше не всегда оценивает все аргументы; она
прекращает оценку аргументов после первого аргумента, который оценивается как
false. Аналогично, функция or теперь прекращает оценку
аргументов после первого аргумента, который оценивается как true. Это имеет значение,
если какой-либо из аргументов является вызовом функции.
image/draw
Резервные реализации Draw и DrawMask
(используются, когда аргументы не являются наиболее распространенными типами изображений) теперь
быстрее, когда эти аргументы реализуют необязательные
draw.RGBA64Image
и image.RGBA64Image
интерфейсы, которые были добавлены в Go 1.17.
net
net.Error.Temporary устарел.
net/http
В целях WebAssembly, поля методов Dial, DialContext,
DialTLS и DialTLSContext в
Transport
теперь будут корректно использоваться, если они заданы, для совершения HTTP-запросов.
Новая функция
Cookie.Valid
сообщает, является ли cookie корректной.
Новая функция
MaxBytesHandler
создаёт Handler, который оборачивает свой
ResponseWriter и Request.Body с помощью
MaxBytesReader.
При поиске доменного имени, содержащего не-ASCII символы, преобразование Unicode в ASCII теперь выполняется в соответствии с Nontransitional Processing, как определено в стандарте Unicode IDNA Compatibility Processing (UTS #46). Интерпретация четырёх различных символов изменена: ß, ς, zero-width joiner U+200D и zero-width non-joiner U+200C. Nontransitional Processing согласуется с большинством приложений и веб-браузеров.
os/user
User.GroupIds
теперь использует нативную реализацию на Go, когда cgo недоступен.
reflect
Новые методы
Value.SetIterKey
и Value.SetIterValue
устанавливают значение Value, используя итератор карты в качестве источника. Они эквивалентны
Value.Set(iter.Key()) и Value.Set(iter.Value()), но
выполняют меньше выделений памяти.
Новый метод
Value.UnsafePointer
возвращает значение Value как unsafe.Pointer.
Это позволяет вызывающим функциям перейти от использования
Value.UnsafeAddr
и Value.Pointer,
устраняя необходимость выполнять преобразования uintptr в unsafe.Pointer в месте вызова (так как правила unsafe.Pointer требуют).
Новый метод
MapIter.Reset
меняет свой получатель для итерации по другой карте.
Использование
MapIter.Reset
позволяет выполнять итерацию без выделения памяти по множеству карт.
К ряду методов (
Value.CanInt,
Value.CanUint,
Value.CanFloat,
Value.CanComplex
)
были добавлены в
Value
для проверки, является ли преобразование безопасным.
Добавлен метод
Value.FieldByIndexErr
для избежания паники, которая возникает при вызове
Value.FieldByIndex
при переходе через nil указатель к встроенной структуре.
reflect.Ptr и
reflect.PtrTo
были переименованы в
reflect.Pointer и
reflect.PointerTo,
соответственно, для согласованности с остальными частями пакета reflect.
Старые имена будут продолжать работать, но будут помечены как устаревшие (deprecated) в будущих релизах Go.
regexp
Пакет regexp
теперь обрабатывает каждый недопустимый байт UTF-8 строки как U+FFFD.
runtime/debug
Структура BuildInfo
имеет два новых поля, содержащих дополнительную информацию о том, как была собрана бинарная программа:
GoVersionхранит версию Go, использованную для сборки бинарного файла.Settingsявляется срезом структурBuildSettings, хранящих пары ключ-значение, описывающие сборку.
runtime/pprof
Профайлер CPU теперь использует таймеры на уровне потоков (per-thread timers) в Linux. Это увеличивает максимальное потребление CPU, которое может быть замечено профайлером, и снижает некоторые виды искажений (bias).
strconv
strconv.Unquote
теперь отклоняет полуслова суррогатной пары Unicode.
strings
Новая функция Cut
разбивает строку string вокруг разделителя. Она может заменить и упростить множество распространённых случаев использования
Index,
IndexByte,
IndexRune
и SplitN.
Новая функция Clone
копирует входную строку string, при этом возвращаемая клонированная строка не ссылается на память входной строки.
Trim, TrimLeft,
и TrimRight теперь работают без выделения памяти и, особенно для
маленьких ASCII наборов символов, могут быть до 10 раз быстрее.
Функция Title теперь устарела. Она не
обрабатывает знаки пунктуации Юникода и правила капитализации, специфичные для языков, и была заменена пакетом
golang.org/x/text/cases.
sync
Новые методы
Mutex.TryLock,
RWMutex.TryLock и
RWMutex.TryRLock,
приобретут блокировку, если она в данный момент не удерживается.
syscall
Введена новая функция SyscallN
для Windows, позволяющая вызывать функции с произвольным числом аргументов. В результате,
Syscall,
Syscall6,
Syscall9,
Syscall12,
Syscall15 и
Syscall18 являются
устаревшими и заменены на SyscallN.
SysProcAttr.Pdeathsig
теперь поддерживается в FreeBSD.
syscall/js
Интерфейс Wrapper был удалён.
testing
Приоритет оператора / в аргументах для -run и
-bench был повышен. A/B|C/D раньше
обрабатывалось как A/(B|C)/D и теперь обрабатывается как
(A/B)|(C/D).
Если опция -run не выбирает ни одного теста, то
опция -count игнорируется. Это может изменить поведение
существующих тестов в маловероятном случае, когда тест изменяет набор подтестов,
которые запускаются каждый раз при вызове функции теста.
Новый тип testing.F
используется новой поддержкой фаззинга, описанной выше.
Тесты теперь также поддерживают командные строки
опции -test.fuzz, -test.fuzztime и
-test.fuzzminimizetime.
text/template
Внутри конвейера range новая команда
{{break}} завершит цикл преждевременно, а новая команда
{{continue}} немедленно начнёт следующую итерацию цикла.
Функция and больше не всегда оценивает все аргументы; она
останавливает оценку аргументов после первого аргумента, который оценивается как
false. Аналогично, функция or теперь также прекращает оценку
аргументов после первого аргумента, который оценивается как true. Это имеет значение,
если любой из аргументов является вызовом функции.
text/template/parse
Пакет поддерживает новые команды
text/template и
html/template
{{break}} через новую константу
NodeBreak
и новый тип
BreakNode,
а также аналогично поддерживает новую команду {{continue}}
через новую константу
NodeContinue
и новый тип
ContinueNode.
unicode/utf8
Новая функция AppendRune добавляет кодирование UTF-8 символа типа rune в []byte.