Как стать автором
Обновить

Go 1.24

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров7.8K

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.

Подведение итогов

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

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 23: ↑14 и ↓9+5
Комментарии20

Публикации

Истории

Работа

Go разработчик
78 вакансий

Ближайшие события

19 марта – 28 апреля
Экспедиция «Рэйдикс»
Нижний НовгородЕкатеринбургНовосибирскВладивостокИжевскКазаньТюменьУфаИркутскЧелябинскСамараХабаровскКрасноярскОмск
24 апреля
VK Go Meetup 2025
Санкт-ПетербургОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
14 мая
LinkMeetup
Москва
5 июня
Конференция TechRec AI&HR 2025
МоскваОнлайн
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область