January 5, 2023
Представлен Go 1.20 RC2
Представлен второй релиз-кандидат Go 1.20. Что нового:
Изменения на уровне языка
- Расширены возможности по приведению слайсов к поинтерам на массив. Например, теперь можно писать
[4]byte(x)
вместо*(*[4]byte(x))
, гдеx
— это слайс; - В
unsafe
добавлены функцииSliceData
,String
иStringData
. Данные функции позволяют конструировать и деконструировать строки и слайсы; - Спецификация*: теперь поля структур сравниваются по одному за раз в порядке их объявления в структуре. Сравнение прекращается при первом несовпадении;
- Спецификация*: массивы также теперь сравниваются поэлементно по одному за раз.
- Типы, которые можно сравнивать, теперь удовлетворяют констрейн
comparable
, даже если аргументы для параметризованных типов строго сравнивать нельзя.
*Данные изменения представлены только в спецификации и отражают уже существующее поведение компилятора.
Инструменты
- Скомпилированные пакеты из стандартной библиотеки больше не хранятся в
$GOROOT/pkg
и не поставляются вместо с Go. Теперь такие пакеты собираются и кэшируются по необходимости. Благодаря этому уменьшился размер дистрибутива Go; - Теперь можно передать флаг
-C <dir>
, чтобы задать рабочую директорию для подкомандыgo
; go build
иgo test
больше не принимают флаг-i
— он был помечен как устаревший ещё в версии 1.16;go generate
принимает новый флаг--skip=<pattern>
, позволяющий пропустить директивы//go:generate
, соответствующие паттерну;- Аналогичное нововведение и для
go test
👆; go build
иgo install
и некоторые другие команды принимают новый флаг--pgo
, который включает profile-guided optimization, а также флаг--cover
.
CGO
- CGO теперь выключен по умолчанию в окружениях без тулчейна для Си;
- Пакеты в стандартной библиотеке, использующие CGO были переписаны, и теперь они написаны на «чиcтом» Go. Это же относится к рейс-детектору для macOS. Для остальных операционных систем Си всё ещё требуется для запуска рейс-детектора.
Покрытие
- В Go 1.20 стало возможным собрать покрытие кода не только в юнит-тестах, но и просто в рантайме и интеграционных тестах. Для этого флаг
--cover
и завезли вgo build
иgo install
. При включенном флаге в бинарник с приложением также будет запакован инструментарий для сбора покрытия.
Vet
go vet
теперь обнаруживает многие места неправильного использование ссылочных переменных;- Также встроенный линтер репортит о случаях, когда используется формат 2006-02-01 (yyyy-dd-mm) в функциях
time.Format
иtime.Parse
. Данный формат не является частью какого-либо стандарта, однако часто используется по ошибке при попытке соответствовать стандарту ISO 8601 (yyyy-mm-dd).
Рантайм
- Добавлена поддержка экспериментального способа выделения памяти — memory-safe arena allocation. Данный способ позволяет освобождать много памяти за раз. При правильном использовании это улучшит перфоманс по CPU до 15% в приложениях, часто выделяющих новую память;
- Некоторые внутренние структуры данных сборщика мусора были улучшены, что снизило оверхед на память и улучшило перфоманс по CPU до 2%.
Компилятор
- В Go 1.20 в режиме превью появился profile-guided optimization (PGO). PGO позволяет оптимизировать приложения при компиляции на основе данных после профилирования (в данный момент поддерживается только pprof). Так, например, инлайнинг функций теперь работает менее агрессивно, а бенчмарки показывают прирост производительности в 3-4%.
- Пофикшены некоторые баги, в частности связанные с дженериками;
- Больше нельзя объявить анонимный циклический интерфейс.
Стандартная библиотека
- crypto/ecdh — новый пакет для поддержки протокола Диффи – Хеллмана на эллиптических кривых;
- Появилась возможность соединять несколько ошибок в одну с помощью метода
errors.Join
; - В
net/http
добавили типResponseController
, позволяющий чуть удобнее работать с запросами; - В
httputil
для реверс-прокси добавили функциюRewrite
, которая должна послужить заменой функцииDirector
. Новый хук позволяет работать также и со входящими запросами, в отличие отDirector
; ProxyRequest.SetURL
— новый метод, который перенаправляет запрос в указанную точку назначения и устанавливает заголовокHost
для исходящего запроса. Может быть использован в качестве замены прокси, создаваемого с помощью функцииNewSingleHostReverseProxy
;- Также добавлен метод
ProxyRequest.SetXForwarded
для задания соответствующих хедеров. При использованииRewrite
данные хедеры по умолчанию не устанавливаются. - И множество минорных изменений.
Полный список изменений: https://tip.golang.org/doc/go1.20