пятница, 8 апреля 2022 г.

Релиз Go 1.18

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

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


Дженерики

Go 1.18 включает в себя реализацию дженериков (общих типов). Это включает в себя серьезные, но полностью совместимые с предыдущими версиями, изменения языка.

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

Хотя считается, что новые функции языка хорошо разработаны и четко определены, возможно, допущены ошибки. Важно подчеркнуть, что гарантия совместимости с Go 1 гласит: "Если возникает необходимость устранить несоответствие или неполноту в спецификации, решение проблемы может повлиять на смысл или законность существующих программ. Мы оставляем за собой право решать такие проблемы, включая обновление реализации". В нем также говорится: "Если в компиляторе или библиотеке есть ошибка, нарушающая спецификацию, программа, зависящая от ошибочного поведения, может сломаться, если ошибка будет исправлена. Мы оставляем за собой право исправлять такие ошибки". Другими словами, возможно, что будет код, использующий дженерики, который будет работать с релизом 1.18, но сломается в более поздних релизах. Не планируется и не ожидается подобных изменений. Однако поломка программ 1.18 в будущих релизах может оказаться необходимой по причинам, которые сегодня не возможно предвидеть. Будет сведена к минимуму любая такая поломка, но не возможно гарантировать, что ее не будет совсем.

Ниже приведен список наиболее заметных изменений.

  • Синтаксис объявлений функций и типов теперь принимает параметры типа.
  • Параметризованные функции и типы могут быть созданы, если за ними следует список аргументов типа в квадратных скобках.
  • В набор операторов и знаков препинания добавлен новый токен ~.
  • Синтаксис типов интерфейсов теперь позволяет встраивать произвольные типы (а не только имена типов интерфейсов), а также элементы типа union и ~T. Такие интерфейсы могут использоваться только как ограничения типа. Интерфейс теперь определяет набор типов, а также набор методов.
  • Новый предварительно объявленный идентификатор any является псевдонимом для пустого интерфейса. Его можно использовать вместо interface{}.
  • Новый предварительно объявленный идентификатор compare — это интерфейс, обозначающий набор всех типов, которые можно сравнивать с помощью == или !=. Его можно использовать только как (или встроенное) ограничение типа.

Есть три экспериментальных пакета, использующих дженерики, которые могут оказаться полезными. Эти пакеты находятся в репозитории 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.19.
  • Компилятор Go не принимает аргументы типа параметра типа с предварительно объявленными функциями real, imag и complex. Планируется убрать это ограничение в Go 1.19.
  • Компилятор Go поддерживает только вызов метода m для значения x типа параметра типа P, если m явно объявлен интерфейсом ограничения P. Точно так же значения метода x.m и выражения метода P.m также поддерживаются только в том случае, если m явно объявлен P, даже если m может находиться в наборе методов P в силу того факта, что все типы в P реализуют m. Планируется убрать это ограничение в Go 1.19.
  • Компилятор Go не поддерживает доступ к полю структуры x.f, где x имеет тип параметра типа, даже если все типы в наборе типов параметра типа имеют поле f. Планируется убрать это ограничение в Go 1.19.
  • Встраивание параметра типа или указателя на параметр типа в качестве безымянного поля в типе структуры не допускается. Точно так же не допускается встраивание параметра типа в тип интерфейса. Будут ли они когда-либо разрешены, в настоящее время неясно.
  • Элемент union с более чем одним термином не может содержать тип интерфейса с непустым набором методов. Будет ли это когда-либо разрешено, пока неясно.

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

Исправление ошибок

Компилятор Go 1.18 теперь правильно сообщает об объявленных, но не используемых ошибках для переменных, которые установлены внутри литерала функции, но никогда не используются. До Go 1.18 компилятор не сообщал об ошибке в таких случаях. Это устраняет давнюю проблему с компилятором. В результате этого изменения (возможно, некорректные) программы могут больше не компилироваться. Необходимое исправление простое: исправить программу, если она действительно была неправильной, или использовать неверную переменную, например, присвоив ей пустой идентификатор _. Поскольку go vet всегда указывал на эту ошибку, количество затронутых программ, вероятно, очень мало.

Компилятор Go 1.18 теперь сообщает о переполнении при передаче константного выражения руны, такого как '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 теперь поддерживают некооперативное вытеснение, предоставляя эту возможность всем четырем портам 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 (это значение по умолчанию).

Инструменты


Фаззинг

Go 1.18 включает в себя реализацию фаззинга.

Имейте в виду, что фаззинг может потреблять много памяти и может повлиять на производительность вашей машины во время ее работы. Также имейте в виду, что механизм фаззинга записывает значения, которые расширяют тестовое покрытие, в каталог кэша фаззинга в $GOCACHE/fuzz во время его работы. В настоящее время нет ограничений на количество файлов или общее количество байтов, которые могут быть записаны в нечеткий кэш, поэтому он может занимать большой объем памяти (возможно, несколько ГБ).

Команда go


go get

go get больше не собирает и не устанавливает пакеты в режиме с поддержкой модулей. go get теперь предназначен для настройки зависимостей в go.mod. По сути, флаг -d всегда включен. Чтобы установить последнюю версию исполняемого файла вне контекста текущего модуля, используйте go install example.com/cmd@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 пакет и содержащий его main модуль находятся в одном репозитории. Эту информацию можно опустить, используя флаг -buildvcs=false.

Кроме того, команда go встраивает информацию о сборке, включая теги сборки и инструмента (установленные с помощью -tags), флаги компилятора, ассемблера и компоновщика (например, -gcflags), включено ли cgo, и если да, то значения переменные среды cgo (например, CGO_CFLAGS). Информация о VCS и сборке может быть прочитана вместе с информацией о модуле с помощью 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 будет переведена в режим рабочей области (workspace mode). В режиме рабочей области (workspace mode) файл go.work будет использоваться для определения набора основных модулей, используемых в качестве корней для разрешения модулей, вместо использования обычно находящегося файла go.mod для указания одного основного модуля.

go build -asan

Команда go build и связанные с ней команды теперь поддерживают флаг -asan, который позволяет взаимодействовать с кодом C (или C++), скомпилированным с помощью address sanitizer (параметр компилятора C -fsanitize=address).

go test

Команда go теперь поддерживает дополнительные параметры командной строки для новой поддержки фаззинга:

  • go test поддерживает параметры -fuzz, -fuzztime и -fuzzminimizetime.
  • go clean поддерживает параметр -fuzzcache.

//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.17 или более позднюю версию в своих файлах go.mod.

gofmt

gofmt теперь одновременно читает и форматирует входные файлы с ограничением памяти, пропорциональным GOMAXPROCS. На машине с несколькими ЦП gofmt теперь должен работать значительно быстрее.

Vet


Обновления для дженериков

Инструмент vet обновлен для поддержки универсального кода. В большинстве случаев он сообщает об ошибке в универсальном коде всякий раз, когда он сообщает об ошибке в эквивалентном неуниверсальном коде после замены параметров типа типом из их набора типов. Например, vet сообщает об ошибке формата в

func Print[T ~int|~string](t T) {
    fmt.Printf("%d", t)
}

потому что он сообщит об ошибке формата в неуниверсальном эквиваленте Print[string]:

func PrintString(x string) {
    fmt.Printf("%d", x)
}

Улучшение точности для существующих проверок

Средства проверки cmd/vet - copylock, printf, sortslice, testinggoroutine - и тесты имеют умеренные улучшения точности для обработки дополнительных шаблонов кода. Это может привести к новым сообщениям об ошибках в существующих пакетах. Например, средство проверки printf теперь отслеживает строки форматирования, созданные путем объединения строковых констант. Поэтому vet сообщит об ошибке в:

// fmt.Printf formatting directive %d is being passed to Println.
// директива форматирования fmt.Printf %d передается в Println.
fmt.Println("%d"+` ≡ x (mod 2)`+"\n", x%2)

Runtime

Сборщик мусора теперь включает источники работы сборщика мусора, не связанные с кучей (например, сканирование стека), при определении частоты запуска. В результате накладные расходы сборщика мусора более предсказуемы, когда эти источники значительны. Для большинства приложений эти изменения будут незначительными; однако некоторые приложения Go теперь могут использовать меньше памяти и тратить больше времени на сборку мусора или наоборот, чем раньше. Предполагаемый обходной путь — настроить GOGC там, где это необходимо.

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

Go 1.17 в целом улучшил форматирование аргументов в трассировке стека, но мог выводить неточные значения для аргументов, переданных в регистрах. В Go 1.18 это улучшено за счет печати вопросительного знака (?) после каждого значения, которое может быть неточным.

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

Компилятор

В Go 1.17 реализован новый способ передачи аргументов и результатов функций с использованием регистров вместо стека в 64-битной архитектуре x86 в некоторых операционных системах. Go 1.18 расширяет список поддерживаемых платформ, включая 64-разрядные ARM (GOARCH=arm64), 64-разрядные PowerPC с обратным порядком байтов и прямым порядком байтов (GOARCH=ppc64, ppc64le), а также 64-разрядную архитектуру x86 (GOARCH=amd64) на все операционные системы. В 64-разрядных системах ARM и 64-разрядных системах PowerPC бенчмаркинг показывает типичное повышение производительности на 10% и более.

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

Теперь компилятор может встраивать функции, которые содержат циклы диапазона или метки для циклов.

Новая опция компилятора -asan поддерживает новую опцию команды go -asan.

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

Из-за изменений в компиляторе, связанных с поддержкой дженериков, скорость компиляции Go 1.18 может быть примерно на 15% ниже, чем скорость компиляции Go 1.17. На время выполнения скомпилированного кода это не влияет. Планируется улучшить скорость компилятора в будущих релизах.

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

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

Новая опция компоновщика -asan поддерживает новую опцию команды go -asan.

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

При сборке релиза 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 или более поздней версии для начальной загрузки, и это изменение должно сделать переход более плавным.

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


Новый пакет debug/buildinfo

Новый пакет debug/buildinfo предоставляет доступ к версиям модулей, информации о контроле версий и флагам сборки, встроенным в исполняемые файлы, созданные командой go. Та же информация также доступна через runtime/debug.ReadBuildInfo для текущего исполняемого файла и через go version -m в командной строке.

Новый пакет net/netip

Новый пакет net/netip определяет новый тип IP-адреса, Addr. По сравнению с существующим типом net.IP тип netip.Addr занимает меньше памяти, является неизменяемым и сравнимым, поэтому он поддерживает == и может использоваться в качестве ключа сопоставления.

В дополнение к 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 поддерживают ввод-вывод без аллокаций.

Пакет 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.19.

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

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

bufio

Новый метод Writer.AvailableBuffer возвращает пустой буфер с возможно непустой емкостью для использования с API-интерфейсами, подобными append. После добавления буфер может быть предоставлен для последующего вызова Write и возможно позволит избежать копирования.

Методы Reader.Reset и Writer.Reset теперь используют размер буфера по умолчанию при вызове объектов с нулевым буфером.

bytes

Новая функция Cut нарезает []byte вокруг разделителя. Она может заменить и упростить многие распространенные способы использования Index, IndexByte, IndexRune и SplitN.

Trim, TrimLeft и TrimRight теперь не требуют выделения памяти и, особенно для небольших фрагментов ASCII, работают до 10 раз быстрее.

Функция Title устарела. Она не обрабатывает пунктуацию Unicode и правила использования заглавных букв для конкретного языка и заменяется пакетом golang.org/x/text/cases.

crypto/elliptic

Реализации кривых P224, P384 и P521 теперь поддерживаются кодом, сгенерированным проектами addchain и fiat-crypto, последний из которых основан на формально проверенной модели арифметических операций. Теперь они используют более безопасные полные формулы и внутренние API. Р-224 и Р-384 теперь примерно в четыре раза быстрее. Все конкретные реализации кривых теперь работают с постоянным временем.

Работа с недопустимыми точками кривой (теми, для которых метод IsOnCurve возвращает false и которые никогда не возвращаются Unmarshal или методом Curve, работающим с допустимой точкой) всегда было неопределенным поведением, может привести к атакам восстановления ключа и теперь не поддерживается новым бэкендом. Если для метода P224, P384 или P521 указана недопустимая точка, этот метод теперь будет возвращать случайную точку. Поведение может измениться на явную панику в будущем релизе.

crypto/tls

Новый метод Conn.NetConn позволяет получить доступ к базовому net.Conn.

crypto/x509

Certificate.Verify теперь использует API-интерфейсы платформы для проверки действительности сертификата в macOS и iOS, когда он вызывается с нулевым значением VerifyOpts.Roots или при использовании корневого пула, возвращенного из SystemCertPool.

SystemCertPool теперь доступен в Windows.

В Windows, macOS и iOS, когда в CertPool, возвращенный SystemCertPool, добавлены дополнительные сертификаты, Certificate.Verify выполнит две проверки: одну с использованием API-интерфейсов верификатора платформы и системных корней (roots), а другую с использованием верификатора Go и дополнительных корней (roots). Цепочки, возвращаемые API-интерфейсами верификатора платформы, будут иметь приоритет.

CertPool.Subjects устарел. В Windows, macOS и iOS CertPool, возвращаемый SystemCertPool, будет возвращать пул, который не включает системные корни в срезе, возвращаемом Subjects, поскольку статический список не может должным образом представлять политики платформы и может быть вообще недоступен из API платформы.

Поддержка подписания сертификатов с использованием алгоритмов подписи, зависящих от хэшей MD5 и SHA-1 (MD5WithRSA, SHA1WithRSA и ECDSAWithSHA1), может быть удалена в 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.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 и связанные с ним методы для представления ошибки, связанной с аргументом типа.
  • Новый контекст типа и фабричная функция 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 создает обработчик, который оборачивает свои ResponseWriter и Request.Body в MaxBytesReader.

При поиске доменного имени, содержащего символы, отличные от ASCII, преобразование Unicode в ASCII теперь выполняется в соответствии с непереходной обработкой, как определено в стандарте Unicode IDNA Compatibility Processing (UTS #46). Изменена интерпретация четырех различных рун: ß, ς, соединения нулевой ширины U+200D и соединения нулевой ширины U+200C. Непереходная обработка совместима с большинством приложений и веб-браузеров.

os/user

User.GroupIds теперь использует нативную реализацию Go, когда cgo недоступен.

reflect

Новые методы Value.SetIterKey и Value.SetIterValue устанавливают значение, используя итератор карты в качестве источника. Они эквивалентны 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 добавлен ряд методов ( Value.CanInt, Value.CanUint, Value.CanFloat, Value.CanComplex ) для проверки безопасности преобразования.

Value.FieldByIndexErr был добавлен, чтобы избежать паники, возникающей в Value.FieldByIndex при переходе через нулевой указатель к встроенной структуре.

Reflect.Ptr и Reflect.PtrTo были переименованы в Reflect.Pointer и Reflect.PointerTo соответственно для обеспечения согласованности с остальной частью пакета Reflect. Старые имена продолжат работать, но в будущем релизе Go они будут объявлены устаревшими.

regexp

regexp теперь обрабатывает каждый недопустимый байт строки UTF-8 как U+FFFD.

runtime/debug

Структура BuildInfo имеет два новых поля, содержащих дополнительную информацию о том, как был создан двоичный файл:

  • GoVersion содержит версию Go, используемую для сборки двоичного файла.
  • Settings — это срез структур BuildSettings, содержащий пары ключ/значение, описывающие сборку.

runtime/pprof

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

strconv

strconv.Unquote теперь отклоняет суррогатные половинки Unicode.

strings

Новая функция Cut разрезает строку вокруг разделителя. Он может заменить и упростить многие распространенные способы использования Index, IndexByte, IndexRune и SplitN.

Новая функция Clone копирует входную строку, при этом возвращаемая клонированная строка не ссылается на память входной строки.

Trim, TrimLeft и TrimRight теперь не требуют выделения памяти и, особенно для небольших фрагментов ASCII, работают до 10 раз быстрее.

Функция Title устарела. Она не обрабатывает пунктуацию Unicode и правила использования заглавных букв для конкретного языка и заменяется пакетом golang.org/x/text/cases.

sync

Новые методы Mutex.TryLock, RWMutex.TryLock и RWMutex.TryRLock получат блокировку, если она в данный момент не удерживается.

syscall

Для Windows была введена новая функция SyscallN, позволяющая выполнять вызовы с произвольным количеством аргументов. В результате 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 к []byte.


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