Представлен релиз языка программирования Go 1.22, который развивается компанией Google при участии сообщества как гибридное решение, сочетающее высокую производительность компилируемых языков с такими достоинствами скриптовых языков, как лёгкость написания кода, быстрота разработки и защищённость от ошибок. Код проекта распространяется под лицензией BSD.
Синтаксис Go основан на привычных элементах языка Си с отдельными заимствованиями из языка Оберон. Язык достаточно лаконичен, но при этом код легко читается и воспринимается. Код на языке Go компилируется в обособленные бинарные исполняемые файлы, выполняемые нативно, без использования виртуальной машины (модули профилирования, отладки и другие подсистемы выявления проблем на этапе выполнения интегрируются в виде runtime-компонентов), что позволяет добиться производительности, сопоставимой с программами на языке Си.
Проект изначально разрабатывается с оглядкой на многопоточное программирование и эффективную работу на многоядерных системах, в том числе предоставляя реализованные на уровне операторов средства для организации параллельных вычислений и взаимодействия между параллельно выполняемыми методами. Язык также предоставляет встроенные средства защиты от выхода за допустимые области выделенных блоков памяти и обеспечивает возможность использования сборщика мусора.
Среди изменений в новом выпуске:
- В циклы «for» добавлена поддержка определения диапазонов из целых чисел, например, для перебора значений с 0 до 9 теперь можно использовать цикл «for i := range 10 {...}».
- В циклы «for» добавлена экспериментальная (GOEXPERIMENT=rangefunc) поддержка функций определения диапазона, позволяющая указывать функцию в качестве итератора. Например, «for i, x := range slices.Backward(s) {...}»
- Решена давняя проблема с циклами «for», приводившая при вызове сопрограмм (goroutine) к совместному использованию переменных цикла в разных итерациях. Например, кодтеперь будет выводить «a»,«b» и «c», а не только «c», как было раньше.
values := []string{"a", "b", "c"} for _, v := range values { go func() { fmt.Println(v) done <- true }() }
- Проведена оптимизация работы с памятью в runtime, которая привела к повышению производительности на 1-3% и снижению потребления памяти в большинстве приложений на 1%.
- Продолжена работа по задействованию в компиляторе оптимизаций на основе результатов профилирования кода (PGO - Profile-guided optimization), позволяющих учитывать особенности, определяемые во время выполнения программы. В новой версии в компиляторе задействованы средства девиртуализации для замены непрямых вызовов различных методов на выполнение развёрнутых inline-блоков.
- При включении PGO добавленное изменение позволило повысить производительность большинства программ на 2-14%.
- В компилятор добавлена экспериментальная (GOEXPERIMENT=newinliner) улучшенная реализация механизма развёртывания (inlining) вызовов, использующая эвристику для разделения важных и второстепенных операций.
- В стандартную библиотеку добавлен пакет «math/rand/v2», в котором предложен более целостный API и задействованы более быстрые алгоритмы генерации псевдо-случайных чисел.
- В пакет net/http.ServeMux добавлена возможность указания методов и масок в шаблонах, например, шаблон «GET /static/{id}/» будет применён к запросам с HTTP-методом «GET» и сохранит значение второго сегмента запрошенного пути в идентификаторе «id».
- В пакет database/sql добавлена поддержка типа Null[T], позволяющего сканировать столбцы, которые могут принимать значение NULL. В пакет slices добавлена функция Concat для слияния нескольких слайсов любого типа.
- В командах для работы с рабочими пространствами (коллекциями модулей) предоставлена возможность использования каталога «vendor», содержащего зависимости к содержимому рабочего пространства. Каталог создаётся при выполнении команды «go work vendor» и используется в сборочных командах при выставлении опции "-mod=vendor" (включает по умолчанию при наличии каталога vendor).
Изменения в поведении утилит.
- go get больше не поддерживается за пределами модуля в устаревшем GOPATH режиме (то есть с GO111MODULE=off). Другие команды сборки, такие как go build и go test, будут продолжать работать для устаревших GOPATH программ в течение неопределенного времени.
- go mod init больше не пытается импортировать требования к модулям из файлов конфигурации для других инструментов поставщиков (таких как Gopkg.lock).
- go test -cover теперь печатает сводные данные о покрытии для покрываемых пакетов, у которых нет собственных тестовых файлов. До Go 1.22 go test -cover для такого пакета сообщал бы
? mymod/mypack [no test files]
и теперь с Go 1.22 функции в пакете считаются непокрытыми:
Обратите внимание: если пакет вообще не содержит исполняемого кода, мы не можем сообщить о значимом проценте покрытия; для таких пакетов go test будет продолжать сообщать об отсутствии тестовых файлов.mymod/mypack coverage: 0.0% of statements
- Веб-интерфейс инструмента trace был слегка обновлен в рамках работы по поддержке нового трассировщика, решены некоторые проблемы и улучшена читабельность различных страниц. Веб-интерфейс теперь поддерживает изучение трассировок в поточно-ориентированном представлении. Средство просмотра трассировки теперь также отображает полную продолжительность всех системных вызовов. Эти улучшения применимы только для просмотра трассировок, созданных программами, созданными на Go 1.22 или новее. В будущем выпуске некоторые из этих улучшений будут внесены в трассировки, создаваемые старой версией Go.
- Среда выполнения теперь хранит метаданные сборки мусора на основе типов ближе к каждому объекту кучи. Это изменение также снижает затраты памяти большинства программ Go примерно на 1% за счет дедупликации избыточных метаданных. В некоторых программах улучшение может быть меньшим, поскольку это изменение корректирует границы класса размера распределителя памяти, поэтому некоторые объекты могут быть перемещены на класс размера выше. Следствием этого изменения является то, что адреса некоторых объектов, которые раньше всегда были выровнены по границе 16 байт (или выше), теперь будут выровнены только по границе 8 байт. Некоторые программы, использующие инструкции ассемблера, требующие, чтобы адреса памяти были выровнены по размеру более 8 байт и полагаются на предыдущее поведение выравнивания распределителя памяти, могут выйти из строя, но мы ожидаем, что такие программы будут редки. Такие программы могут быть созданы с GOEXPERIMENT=noallocheaders с возможностью возврата к старой модели метаданных и восстановления предыдущего поведения выравнивания, но владельцам пакетов следует обновить свой ассемблерный код, чтобы избежать предположения о выравнивании, поскольку этот обходной путь будет удален в будущем выпуске.
- Как упоминалось в примечаниях к выпуску Go 1.20, Go 1.22 теперь требует финальной версии Go 1.20 или новее для начальной сборки. Мы ожидаем, что Go 1.24 потребует финальной версии Go 1.22 или более поздней версии для начальной сборки.
Оригинал (go.dev)