
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.