Примечания к выпуску 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 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: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 добавлены следующие элементы:

go/constant

Новый метод Kind.String возвращает человекочитаемое имя для типа получателя.

go/token

Новая константа TILDE представляет токен ~ согласно предложению Дополнения к go/ast и go/token для поддержки параметризованных функций и типов .

go/types

Новое поле Config.GoVersion устанавливает принимаемую версию языка Go.

Согласно предложению Дополнения к go/types для поддержки параметров типов в пакет go/types добавлены следующие изменения:

Предикаты 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 имеет два новых поля, содержащих дополнительную информацию о том, как была собрана бинарная программа:

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.

GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang