Как стать автором
Поиск
Написать публикацию
Обновить

Go 1.24

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

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

Публикации

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