
Go 1.24 (релиз запланирован на февраль 2025 года) принесет множество новых мощных функций, улучшений производительности и долгожданных исправлений. В этой статье я в доступной форме расскажу о самых интересных частях грядущего релиза, подчеркнув не только то, как использовать эти новые возможности, но и то, почему они важны.
Изменения в языке
Одним из самых значительных изменений на уровне языка в Go 1.24 стала полная поддержка псевдонимов общих типов. Теперь вы можете определять псевдонимы типов с параметрами так же, как и определенные общие типы, что делает ваш код более выразительным. Хотя вы, возможно, уже знакомы с «псевдонимами типов», дополнительная возможность параметризации поможет сократить дублирование в коде, который в значительной степени опирается на дженерики.
Пример:
// Теперь это возможно в Go 1.24
type NumberList[T ~int | ~float64] = []T
// Вы можете использовать NumberList везде, где использовался бы обычный фрагмент T.
func SumNumbers[T ~int | ~float64](nums NumberList[T]) T {
var sum T
for _, n := range nums {
sum += n
}
return sum
}
На данный момент, если у вас возникнут проблемы, вы можете отключить эту функцию с помощью:
export GOEXPERIMENT=noaliastypeparams
Однако в Go 1.25 он должен стать постоянным, так что будьте готовы к его внедрению.
Основные усовершенствования инструментария
Отслеживание зависимостей исполняемых файлов
Особым дополнением является то, что Go 1.24 теперь позволяет модулям отслеживать «инструментальные» зависимости с помощью директив tool
в go.mod
. Это проще, чем старый подход, при котором фиктивные _
импорты добавлялись в специальный файл tools.go
.
Пример:
module myAwesomeProject
go 1.24
tool "golang.org/x/tools/cmd/stringer@v0.9.0"
require (
// зависимости от ваших библиотек
)
После объявления вы можете установить или обновить эти инструменты с помощью таких команд, как:
go install tool
Эта команда использует инструмент meta-pattern для установки всех инструментов, определенных в go.mod. Чтобы добавить или обновить один инструмент.
go get -tool golang.org/x/tools/cmd/stringer@latest
Новый флаг -json для go build и go install
Разработчикам, создающим сложные инструменты на основе системы сборки Go, понравится новая опция -json:
go build -json ./...
Это выводит структурированный JSON, давая вам полное представление о шагах сборки, зависимостях, предупреждениях и ошибках в удобном для обработки формате. Тот же подход работает с go install -json и прекрасно сочетается с выводом результатов тестирования, когда вы запускаете go test -json.
Улучшенный тестовый выход
Если вы используете go test -json
в качестве инструментария или интеграции в конвейеры CI, имейте в виду, что теперь вы будете видеть сообщения сборки и в JSON-формате. Это может помочь унифицировать журналы, но если у вас есть существующий парсер, вам, возможно, придется его обновить. Если это становится проблематичным, установите:
GODEBUG=gotestjsonbuildtext=1
чтобы вернуться к текстовому выводу сборки в go test -json
.
Улучшения Cgo
Для тех, кто работает с кодом на С из Go:
Аннотации без экранирования: Теперь вы можете объявить некоторые функции C как не экранирующие передаваемые ссылки на память. Например:
// #cgo noescape myCFn
// void myCFn(int* buf);
import "C"
Это сообщает компилятору Go, что myCFn не будет хранить или сохранять ссылки на свои аргументы, что позволяет проводить более агрессивную оптимизацию.
Нет аннотаций обратных вызовов: Аналогично, nocallback указывает, что функция C не будет вызывать обратные вызовы Go, что также может повысить производительность.
Лучше обнаружение несовместимых объявлений: Если одна и та же C-функция объявлена с разными подписями в разных файлах, cgo теперь будет надежно определять и сообщать об ошибке, а не молча генерировать неправильный вызов.
Обновления Objdump
Утилита go tool objdump
теперь поддерживает дизассемблирование на дополнительных архитектурах: Loong64, riscv64 и s390x. Если вы работаете на одной из этих платформ, это может сильно помочь при отладке низкоуровневых проблем с производительностью или памятью.
Ветеринар: больше проверок для более безопасного кода
Анализатор тестов
В Go 1.24 появился новый анализатор тестов, который выявляет ошибки в сигнатурах тестируемых функций - например, неправильно сформированное имя теста или пример, ссылающийся на несуществующий идентификатор. Он автоматически включается в go test
, так что ваш тестовый код получает еще больше проверок безопасности из коробки.
Обновленный анализатор printf
Если вы выполняете вызовы типа fmt.Printf(s)
, где s
- переменная времени выполнения (не константа), анализатор теперь предупреждает вас об этом. Использование %s
или fmt.Print(s)
обычно более понятно, особенно если s
может содержать символы %
.
Обновленный анализатор тегов сборки
Теперь помечаются недопустимые ограничения сборки, например //go:build go1.23.1
(точечные релизы не допустимы в тегах сборки).
Анализатор copylock
Если у вас есть переменная for-loop, содержащая sync.Mutex
(или подобную блокировку), вы получите предупреждение. Это помогает предотвратить тонкие ошибки параллелизма, появившиеся в Go 1.22, где такие переменные цикла копируются каждую итерацию.
Время выполнения и производительность
Появилась новая встроенная реализация карт (Swiss Tables) и переработанный внутренний мьютекс времени выполнения. В целом, вы можете увидеть снижение использования процессора на 2-3 %, но результаты зависят от рабочей нагрузки. Если вам нужно вернуться к старому поведению (для отладки или проверки регрессии производительности), установите:
GOEXPERIMENT=noswissmap,nospinbitmutex
в вашей среде сборки.
Изменения в компиляторе, компоновщике и Bootstrap
Компилятор стал строже относиться к cgo-генерируемым типам в качестве приемников методов. Теперь вы не можете обойти это ограничение с помощью псевдотипа.
Компоновщик теперь по умолчанию выводит идентификатор сборки GNU на ELF-системах и UUID на macOS. Вы можете отключить или отменить это с помощью флагов -B.
Для загрузки Go 1.24 теперь требуется Go 1.22.6 или более поздняя версия.
Основные моменты стандартной библиотеки
Ограниченный каталогом доступ к файловой системе
Новый тип os.Root
поможет вам безопасно работать в «песочнице» из одного каталога. Вы создаете его с помощью os.OpenRoot
, а затем вызываете такие методы, как Create
, Open
, Stat
и Mkdir
, непосредственно из этого корня. Это гарантирует, что вы не сможете случайно выйти за пределы «песочницы» каталогов, даже через симлинки.
Пример:
rootDir, err := os.OpenRoot("/path/to/some/dir")
if err != nil {
log.Fatal(err)
}
defer rootDir.Close()
file, err := rootDir.Create("mydata.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// ...
Новая контрольная функция: testing.B.Loop
Попрощайтесь с немного неудобным шаблоном for i := 0; i < b.N; i++ { ... }
. Теперь вы можете написать:
func BenchmarkMyFunc(b *testing.B) {
b.Loop(func() {
MyFunc()
})
}
Это гарантирует, что каждая итерация будет строго учтена, а все параметры/результаты функции останутся живыми - это поможет вам избежать странных оптимизаций компилятора, которые могут испортить ваш бенчмарк.
Улучшенные финализаторы: runtime.AddCleanup
В то время как runtime.SetFinalizer
может быть сложным, runtime.AddCleanup
стремится быть более интуитивным. Он запускает указанную функцию после того, как объект собран, и даже позволяет использовать несколько функций очистки для одного объекта, не вызывая циклов или утечек памяти.
Пример:
type Resource struct {
// ...
}
func release(res *Resource) {
fmt.Println("Resource is freed")
// close handles, free memory, etc.
}
func makeResource() *Resource {
r := &Resource{}
runtime.AddCleanup(r, release)
return r
}
Указатели week
Новый пакет weak
предоставляет указатели, которые не препятствуют сборке мусора для своих целевых объектов. Это очень важно для построения кэшей или карт канонизации.
Новые crypto/mlkem, crypto/hkdf, crypto/pbkdf2, crypto/sha3
ML-KEM (Kyber): Механизм постквантового обмена ключами, указанный в FIPS 203.
HKDF: Функция выведения ключей на основе HMAC для генерации защищенных ключей от мастера.
PBKDF2: идеально подходит для шифрования на основе паролей, как широко рекомендуется в RFC 8018.
SHA-3: Официально входит в стандартную библиотеку Go, так что вы можете работать с
sha3.New224/256/384/512
и семейством cSHAKE с расширенным выходом прямо из коробки.
Изменения в стандартной библиотеке Go
Вот основные обновления:
Итераторы для
bytes
иstrings
: Функции, такие какLines
,SplitSeq
и другие, теперь возвращают итераторы вместо срезов. Это делает их более эффективными с точки зрения памяти при работе с большими данными.crypto/aes
,crypto/cipher
,crypto/rand
: Некоторые методы были устаревшими или заменены для улучшения безопасности и удобства использования. Например, функцияNewGCMWithRandomNonce
теперь автоматически добавляет случайныйnonce
.crypto/rsa
: Ключи размером менее 1024 бит теперь запрещены по умолчанию. Эту настройку можно отключить для тестирования, но крайне не рекомендуется использовать такие ключи в продуктивных средах.log/slog
: Добавлен новыйDiscardHandler
, который никогда ничего не выводит. Это удобно, если нужно временно отключить логи, не удаляя их из кода.sync.Map
: Внутренняя реализация была улучшена для повышения производительности при работе с конкурентными процессами, особенно при модификации больших карт или независимых наборов ключей.testing.T.Context
: Теперь каждый тест содержит встроенныйcontext.Context
, который отменяется по завершении теста. Также добавлены методыt.Chdir
иb.Chdir
для упрощения работы с изменениями текущей директории в рамках конкретного теста.
Изменения, связанные с платформами и портами
Linux: Минимально поддерживаемая версия ядра теперь — 3.2.
macOS: Поддержка macOS 11 Big Sur будет прекращена в Go 1.25. Пользователи Big Sur могут продолжать использовать Go 1.24, но это временное решение, и обновление системы потребуется в ближайшем будущем.
WebAssembly:
Более гибкие типы аргументов для функций
go:wasmexport
иgo:wasmimport
.Появилась возможность собирать реакторы или библиотеки с помощью
GOOS=wasip1 GOARCH=wasm -buildmode=c-shared
.
Windows:
Порт для Windows/ARM отмечен как проблемный.
Метод
os/user.Current()
теперь работает значительно быстрее, если вы находитесь в медленном домене, и поддерживает системные учетные записи, такие какNT AUTHORITY\LOCAL SERVICE
.