пятница, 19 сентября 2025 г.

Релиз Go 1.25

Версия Go 1.25 выходит в августе 2025 года спустя шесть месяцев после выпуска Go 1.24. Большинство изменений касаются инструментов сборки, среды исполнения и библиотек. Как и раньше, релиз сохраняет совместимость с обещаниями Go 1 относительно поддержки совместимости. Ожидается, что почти все программы на Go будут продолжать компилироваться и выполняться аналогично предыдущим версиям.

Изменения в языке

В версии Go 1.25 отсутствуют изменения в самом языке программирования, влияющие на существующие программы. Однако спецификация языка была обновлена, убрав понятие базовых типов в пользу четкого описания типов.

Инструменты

Команда go

Опция -asan, используемая командой go build, теперь по умолчанию включает проверку утечек памяти при завершении программы. Если память, выделенная средствами C, не освобождается и не используется другим кодом, эта проверка выдаст ошибку. Проверку можно отключить, установив переменную окружения ASAN_OPTIONS=detect_leaks=0.

Теперь дистрибутив Go включает меньше предварительно собранных бинарников инструментов. Основные инструменты цепочки сборки, такие как компилятор и линкер, остаются включенными, однако дополнительные утилиты будут собираться и запускаться динамически командой go tool, когда это потребуется.

Новая директива ignore в файле go.mod позволяет игнорировать определенные каталоги командами go. Файлы внутри указанных каталогов и их подпапок не будут учитываться при обработке пакетов с шаблонами вроде all или ./..., хотя сами файлы останутся доступными в архивах модулей.

Команда go doc получила новую опцию -http, позволяющую запустить локальный сервер документации, открываемый автоматически в браузере.

Опция -m -json команды go version выводит структуру runtime/debug.BuildInfo в формате JSON.

Команда go теперь поддерживает модули, размещённые в подпапках репозиториев, благодаря синтаксису <meta name="go-import" content="root-path vcs repo-url subdir">, указывая, что путь модуля соответствует указанному пути подпапки репозитория.

Новый шаблонный паттерн пакета work выбирает пакеты рабочего пространства (ранее называемые основными модулями), включая либо единственный рабочий модуль в режиме модулей, либо группу рабочих пространств в рабочем пространстве.

При обновлении строки go в файлах go.mod или go.work команда больше не добавляет строку инструментальной цепи, фиксируя версию инструмента.

Утилита проверки кода go vet

Утилита go vet пополнилась новыми проверочными инструментами:

  • Анализатор waitgroup, выявляющий неправильное использование метода sync.WaitGroup.Add.
  • Анализатор hostport, предупреждающий о некорректном формировании адресов вида fmt.Sprintf("%s:%d", host, port) для функций типа net.Dial, поскольку это неправильно работает с IPv6. Вместо этого рекомендуется использовать метод net.JoinHostPort.

Среда исполнения (runtime)

Контейнер-зависимый параметр

По умолчанию значение параметра GOMAXPROCS изменилось следующим образом:

  • В Linux среда исполнения рассматривает ограничение пропускной способности процессора контейнера, если оно установлено. Если предел ниже числа доступных ядер, GOMAXPROCS принимает минимальное значение. Это особенно актуально для контейнерных сред вроде Kubernetes, где ограничения ЦПУ соответствуют настройкам "лимит ЦПУ". Параметр "запросы ЦПУ" системой не учитывается.
  • Во всех операционных системах среда периодически обновляет значение GOMAXPROCS, если изменяется число доступных ядер или лимит пропускной способности контейнера.

Эти настройки отключаются вручную, если параметр GOMAXPROCS установлен заранее (через переменную окружения или методом runtime.GOMAXPROCS), либо принудительно через опции GODEBUG: containermaxprocs=0 и updatemaxprocs=0.

Чтобы поддерживать обновление лимитов контейнера, среда выполнения хранит кэшированные файловые дескрипторы для конфигурационных файлов группы управления (cgroups) на протяжении всего срока службы процесса.

Новый экспериментальный сборщик мусора

В Go 1.25 представлен новый экспериментальный сборщик мусора, который улучшает производительность разметки и сканирования мелких объектов посредством оптимизации размещения данных и эффективного использования ресурсов процессора. Предполагается уменьшение накладных расходов на сборку мусора примерно на 10–40%, особенно в приложениях, активно использующих сборку мусора.

Для активации нового сборщика необходимо задать переменную среды GOEXPERIMENT=greenteagc при сборке приложения. Ожидается дальнейшее развитие и улучшение дизайна сборщика, поэтому разработчики приглашаются к участию в экспериментах и обсуждению.

Запись трейсов на лету (Trace flight recorder)

Механизм трассировки выполнения, традиционно полезный, но дорогой ресурсоемкий инструмент, дополнен новым API runtime/trace.FlightRecorder. Он записывает трейсы выполнения программы в кольцевой буфер в памяти, позволяя сохранять трассировку в компактном виде. Приложение может вызвать метод FlightRecorder.WriteTo, чтобы записать последние секунды трейса в файл при возникновении значимых событий.

Размер и продолжительность сохраняемого трейса можно настроить через конфигурацию FlightRecorderConfig.

Изменение вывода сообщений паники

Отныне при выходе программы из-за необработанного восстановления паники (repanic) повтор сообщения паники устранён. Ранее вывод выглядел так:

panic: PANIC [recovered]
panic: PANIC

Теперь вывод выглядит проще:

panic: PANIC [recovered, repanicked]

Названия виртуальных областей памяти (VMA) на Linux

В Linux с поддержкой именования виртуальных областей памяти (VMA) Go автоматически аннотирует виртуальные участки памяти, используемые процессом, поясняя их назначение. Например, для кучи памяти будет создано имя вида [anon: Go: heap]. Аннотацию можно отключить через GODEBUG-параметр decoratemappings=0.

Компилятор

Ошибка с нулевым указателем

В Go 1.25 исправлена ошибка компилятора, появившаяся в Go 1.21, которая приводила к неправильному отложению проверки на ноль указателя. Следующая программа, работавшая ранее ошибочно, теперь корректно генерирует исключение:

package main
import "os"

func main() {
    f, err := os.Open("nonExistentFile")
    name := f.Name()
    if err != nil {
        return
    }
    println(name)
}

Проблема заключалась в том, что обращение к результатам вызова происходило до проверки ошибки. Если произошла ошибка открытия файла, указатель f мог оказаться пустым, вызывая исключение при обращении к нему. Теперь проверка производится сразу после возможного возникновения ошибки.

Поддержка формата DWARF5

Компилятор и линкер в Go 1.25 теперь генерируют отладочную информацию, используя DWARF 5. Новая версия сокращает пространство, необходимое для хранения отладочной информации в двоичных файлах Go, и уменьшает время компоновки, особенно для больших бинарников Go.

Генерация DWARF 5 может быть отключена путем установки переменной окружения GOEXPERIMENT=nodwarf5 во время сборки (эта опция может быть удалена в будущих релизах Go).

Более быстрые срезы

Теперь компилятор способен выделять память для среза непосредственно на стеке в большем количестве случаев, что улучшает производительность. Это изменение потенциально усиливает эффект некорректного использования unsafe.Pointer. Для отслеживания проблем с такими ошибками можно воспользоваться инструментом bisect с флагом -compile=variablemake. Все новые стековые выделения памяти могут быть отключены с помощью опции -gcflags=all=-d=variablemakehash=n.

Линкер

Линкер теперь принимает новый аргумент командной строки -funcalign=N, задающий выравнивание точек входа функций. Значение по умолчанию зависит от платформы и остается неизменным в данном релизе.

Стандартная библиотека

Новый пакет testing/synctest

Новый пакет testing/synctest обеспечивает поддержку тестирования конкурентного кода. Метод Test запускает тестовую функцию внутри изолированного "пузыря". Внутри пузыря виртуализируется время: функции пакета time работают с фиктивными часами, и часы продвигаются вперед мгновенно, если все горутины заблокированы.

Метод Wait ожидает блокировки всех горутин текущего пузыря.

Этот пакет впервые появился в Go 1.24 под экспериментальной настройкой GOEXPERIMENT=synctest, однако тогда имел немного иной интерфейс. Эксперимент теперь считается завершённым и доступен по умолчанию. Старая реализация доступна, если установлена настройка GOEXPERIMENT=synctest, но будет удалена в Go 1.26.

Новый экспериментальный пакет encoding/json/v2

Версия Go 1.25 включает новую экспериментальную реализацию обработки JSON, которую можно включить путём установки переменной среды GOEXPERIMENT=jsonv2 во время сборки.

При включении становятся доступными два новых пакета:

  • Пакет encoding/json/v2 представляет собой значительное обновление существующего пакета encoding/json.
  • Пакет encoding/json/jsontext предоставляет низкоуровневую обработку синтаксиса JSON.

Кроме того, при включённой настройке GOEXPERIMENT=jsonv2 поведение пакета encoding/json меняется следующим образом:

  • Использует новую реализацию JSON. Хотя поведение маршалинга и демаршалинга остаётся прежним, тексты ошибок, возвращаемых функциями пакета, могут отличаться.
  • Появляется ряд новых настроек, позволяющих конфигурировать процесс маршализации и демаршализации.

Новая реализация работает значительно лучше существующей во многих сценариях. В целом, производительность кодирования у обеих реализаций одинакова, а декодирование в новой реализации значительно быстрее. Более подробный анализ в репозитории github.com/go-json-experiment/jsonbench.

Пользователей пакета encoding/json настоятельно призывают протестировать свою программу с активированной настройкой GOEXPERIMENT=jsonv2, чтобы выявить возможные проблемы совместимости с новой реализацией.

Ожидается дальнейшее развитие дизайна пакета encoding/json/v2. Разработчикам рекомендуется попробовать новый API и оставить отзывы на странице предложений.

Незначительные изменения библиотеки

archive/tar

Реализация метода Writer.AddFS теперь поддерживает символические ссылки для файловых систем, реализующих интерфейс io/fs.ReadLinkFS. Это позволяет правильно обрабатывать символьные ссылки при архивировании файлов.

encoding/asn1

Методы Unmarshal и UnmarshalWithParams теперь обрабатывают типы ASN.1 T61String и BMPString более последовательно. Некоторые некорректные кодировки, которые раньше принимались, теперь будут отклоняться.

crypto

MessageSigner — это новый интерфейс подписи, который могут реализовать подписывающие стороны, желающие самостоятельно хешировать сообщение для подписи. Также представлена новая функция SignMessage, которая пытается обновить интерфейс подписчика до MessageSigner, используя метод MessageSigner.SignMessage в случае успеха и метод Signer.Sign в противном случае. Это можно использовать, когда коду требуется поддержка как Signer, так и MessageSigner.

Изменение параметра fips140 GODEBUG после запуска программы теперь не является операцией. Ранее это было задокументировано как недопустимое и могло вызвать панику.

SHA-1, SHA-256 и SHA-512 теперь работают медленнее на amd64 при отсутствии инструкций AVX2. Все серверные процессоры (и большинство других), выпущенные с 2015 года, поддерживают AVX2.

crypto/ecdsa

Введены новые методы для низкоуровневого представления ключей:

  • ParseRawPrivateKey: парсинг приватного ключа.
  • ParseUncompressedPublicKey: парсинг публичного ключа.
  • PrivateKey.Bytes: получение байтов приватного ключа.
  • PublicKey.Bytes: получение байтов публичного ключа.

Эти методы заменяют необходимость использования функций из пакетов crypto/elliptic и math/big.

При включении режима FIPS 140-3 подпись теперь выполняется в четыре раза быстрее, что сопоставимо с производительностью режима без FIPS.

crypto/ed25519

При включении режима FIPS 140-3 подпись теперь выполняется в четыре раза быстрее, что сопоставимо с производительностью режима без FIPS.

crypto/elliptic

Скрытые и недокументированные методы Inverse и CombinedMult в некоторых реализациях Curve были удалены.

crypto/rsa

PublicKey больше не утверждает, что значение модуля считается секретным. VerifyPKCS1v15 и VerifyPSS уже предупреждали, что все входные данные являются открытыми и могут быть раскрыты, а также существуют математические атаки, позволяющие восстановить модуль из других открытых значений.

Генерация ключей теперь в три раза быстрее.

crypto/sha1

Хеширование теперь выполняется в два раза быстрее на amd64 при наличии инструкций SHA-NI.

crypto/sha3

Новый метод SHA3.Clone реализует hash.Cloner.

Хеширование теперь в два раза быстрее на процессорах Apple M.

crypto/tls

Новое поле ConnectionState.CurveID раскрывает механизм обмена ключами, используемый для установления соединения.

Новый обратный вызов Config.GetEncryptedClientHelloKeys можно использовать для установки EncryptedClientHelloKeys для сервера, который будет использоваться при отправке клиентом расширения Encrypted Client Hello.

Алгоритмы подписи SHA-1 теперь запрещены в рукопожатиях TLS 1.2 в соответствии с RFC 9155. Их можно снова включить, настроив GODEBUG tlssha1=1.

При включенном режиме FIPS 140-3 в TLS 1.2 теперь требуется расширенный главный секрет, а Ed25519 и X25519MLKEM768 теперь разрешены.

Серверы TLS теперь предпочитают самую высокую поддерживаемую версию протокола, даже если она не является наиболее предпочтительной для клиента.

Клиенты и серверы TLS теперь более строго следуют спецификациям и отклоняют нестандартное поведение. Соединения с совместимыми одноранговыми узлами не должны быть затронуты.

crypto/x509

CreateCertificate, CreateCertificateRequest и CreateRevocationList теперь могут принимать интерфейсы подписи crypto.MessageSigner, а также crypto.Signer. Это позволяет этим функциям использовать подписывающие стороны, реализующие интерфейсы «однократной» подписи, где хеширование выполняется в рамках операции подписи, а не вызывающей стороной.

Certificate теперь использует усеченный SHA-256 для заполнения SubjectKeyId, если он отсутствует. Параметр GODEBUG x509sha256skid=0 возвращается к SHA-1.

ParseCertificate теперь отклоняет сертификаты, содержащие расширение BasicConstraints с отрицательным pathLenConstraint.

ParseCertificate теперь обрабатывает строки, закодированные с помощью типов ASN.1 T61String и BMPString, более согласованно. Это может привести к отклонению некоторых ранее принятых некорректных кодировок.

debug/elf

Пакет debug/elf добавляет две новые константы:

  • PT_RISCV_ATTRIBUTES
  • SHT_RISCV_ATTRIBUTES для анализа RISC-V ELF.

go/ast

Функции FilterPackage, PackageExports и MergePackageFiles, а также тип MergeMode и его константы устарели, поскольку предназначены только для использования с давно устаревшими механизмами Object и Package.

Новая функция PreorderStack, как и Inspect, обходит синтаксическое дерево и обеспечивает управление переходом в поддеревья, но для удобства она также предоставляет стек вложенных узлов в каждой точке.

go/parser

Функция ParseDir устарела.

go/token

Новый метод FileSet.AddExistingFiles позволяет добавлять существующие файлы в FileSet или создавать FileSet для произвольного набора файлов, устраняя проблемы, связанные с одним глобальным FileSet в долгоживущих приложениях.

go/types

У Var теперь есть метод Var.Kind, который классифицирует переменную как переменную уровня пакета, получателя, параметра, результата, локальной переменной или поля структуры.

Новая функция LookupSelection ищет поле или метод с заданным именем и типом получателя, как и существующая функция LookupFieldOrMethod, но возвращает результат в виде Selection.

hash

Новый интерфейс XOF может быть реализован с помощью «расширяемых функций вывода» — хэш-функций с произвольной или неограниченной длиной выходных данных, таких как SHAKE.

Хэши, реализующие новый интерфейс Cloner, могут возвращать копию своего состояния. Все реализации хэшей стандартной библиотеки теперь реализуют Cloner.

hash/maphash

Новый метод Hash.Clone реализует hash.Cloner.

io/fs

Новый интерфейс ReadLinkFS обеспечивает возможность чтения символических ссылок в файловой системе.

log/slog

GroupAttrs создаёт групповой атрибут Attr из среза значений Attr.

У записи теперь есть метод Source, возвращающий исходное местоположение или nil, если оно недоступно.

mime/multipart

Новая вспомогательная функция FileContentDisposition создает составные поля заголовка Content-Disposition.

net

LookupMX и Resolver.LookupMX теперь возвращают DNS-имена, которые выглядят как допустимые IP-адреса, а также допустимые доменные имена. Ранее, если сервер имен возвращал IP-адрес в качестве DNS-имени, LookupMX отклонял его, как того требуют RFC. Однако на практике серверы имен иногда возвращают IP-адреса.

В Windows ListenMulticastUDP теперь поддерживает адреса IPv6.

В Windows теперь возможно преобразование между os.File и сетевым подключением. В частности, теперь реализованы функции FileConn, FilePacketConn и FileListener, возвращающие сетевое подключение или прослушиватель, соответствующий открытому файлу. Аналогично, теперь реализованы методы File для TCPConn, UDPConn, UnixConn, IPConn, TCPListener и UnixListener, возвращающие базовый os.File сетевого подключения.

net/http

Новый CrossOriginProtection реализует защиту от подделки межсайтовых запросов (CSRF), отклоняя небезопасные запросы кросс-источника браузера. Он использует современные метаданные Fetch браузера, не требует токенов или файлов cookie и поддерживает обходы на основе источника и шаблона.

os

В Windows функция NewFile теперь поддерживает дескрипторы, открытые для асинхронного ввода-вывода (то есть в вызове syscall.CreateFile указывается syscall.FILE_FLAG_OVERLAPPED). Эти дескрипторы связаны с портом завершения ввода-вывода среды выполнения Go, что обеспечивает следующие преимущества для результирующего файла File:

  • Методы ввода-вывода (File.Read, File.Write, File.ReadAt и File.WriteAt) не блокируют поток ОС.
  • Поддерживаются методы Deadline (File.SetDeadline, File.SetReadDeadline и File.SetWriteDeadline).

Это улучшение особенно полезно для приложений, взаимодействующих через именованные каналы в Windows.

Обратите внимание, что дескриптор может быть связан только с одним портом завершения одновременно. Если дескриптор, предоставленный NewFile, уже связан с портом завершения, возвращаемый файл File понижается до режима синхронного ввода-вывода. В этом случае методы ввода-вывода блокируют поток ОС, а методы с ограничением по времени не действуют.

Файловые системы, возвращаемые DirFS и Root.FS, реализуют новый интерфейс io/fs.ReadLinkFS. CopyFS поддерживает символические ссылки при копировании файловых систем, реализующих io/fs.ReadLinkFS.

Тип Root поддерживает следующие дополнительные методы:

  • Root.Chmod
  • Root.Chown
  • Root.Chtimes
  • Root.Lchown
  • Root.Link
  • Root.MkdirAll
  • Root.ReadFile
  • Root.Readlink
  • Root.RemoveAll
  • Root.Rename
  • Root.Symlink
  • Root.WriteFile

reflect

Новая функция TypeAssert позволяет преобразовать значение Value напрямую в значение Go заданного типа. Это похоже на использование утверждения типа для результата Value.Interface, но позволяет избежать ненужного выделения памяти.

regexp/syntax

Синтаксисы классов символов \p{name} и \P{name} теперь поддерживают имена Any, ASCII, Assigned, Cn и LC, а также псевдонимы категорий Unicode, например, \p{Letter} для \pL. Следуя Unicode TR18, они также используют поиск имён без учёта регистра, игнорируя пробелы, подчёркивания и дефисы.

runtime

Функции очистки, запланированные AddCleanup, теперь выполняются одновременно и параллельно, что делает очистку более эффективной при интенсивном использовании, таком как уникальный пакет. Обратите внимание, что отдельные очистки по-прежнему должны перенаправлять свою работу в новую горутину, если они должны выполняться или блокироваться на длительное время, чтобы избежать блокировки очереди очистки.

Новый параметр GODEBUG=checkfinalizers=1 помогает выявлять распространённые проблемы с финализаторами и очистками, например, описанные в руководстве по сборке мусора. В этом режиме среда выполнения выполняет диагностику на каждом цикле сборки мусора, а также регулярно сообщает длину очереди финализаторов и очистки в stderr, что помогает выявлять проблемы с длительно выполняющимися финализаторами и/или очистками.

Новая функция SetDefaultGOMAXPROCS устанавливает для GOMAXPROCS значение по умолчанию среды выполнения, как если бы переменная окружения GOMAXPROCS не была установлена. Это полезно для включения нового значения GOMAXPROCS по умолчанию, если оно было отключено переменной среды GOMAXPROCS или предыдущим вызовом GOMAXPROCS.

runtime/pprof

Профиль мьютекса для конкуренции за внутренние блокировки во время выполнения теперь корректно указывает на конец критической секции, вызвавшей задержку. Это соответствует поведению профиля для конкуренции за значения sync.Mutex. Настройка runtimecontentionstacks для GODEBUG, которая позволяла включить необычное поведение Go 1.22–1.24 для этой части профиля, теперь удалена.

sync

Новый метод WaitGroup.Go делает общепринятую схему создания и подсчета горутин более удобной.

testing

Новые методы T.Attr, B.Attr и F.Attr выдают атрибут в тестовый журнал. Атрибут — это произвольная комбинация ключа и значения, связанная с тестом.

Например, в тесте с именем TestF метод t.Attr("key", "value") выдаёт:

=== ATTR  TestF key value

С флагом -json атрибуты отображаются как новое действие «attr».

Новый метод Output методов T, B и F предоставляет объект io.Writer, который записывает данные в тот же поток вывода теста, что и TB.Log. Как и в случае с TB.Log, вывод имеет отступ, но не включает номер файла и строки.

Функция AllocsPerRun теперь вызывает панику при запуске параллельных тестов. Результат AllocsPerRun изначально нестабилен при запуске других тестов. Новое поведение паники помогает выявлять такие ошибки.

testing/fstest

MapFS реализует новый интерфейс io/fs.ReadLinkFS. TestFS проверит функциональность интерфейса io/fs.ReadLinkFS, если он реализован. TestFS больше не будет следовать символическим ссылкам, чтобы избежать неограниченной рекурсии.

unicode

Новая карта CategoryAliases предоставляет доступ к псевдонимам категорий, например, «Letter» для «L».

Новые категории Cn и LC определяют неназначенные кодовые точки и буквы с регистром соответственно. Они всегда были определены в Unicode, но были случайно пропущены в более ранних версиях Go. Категория C теперь включает Cn, то есть в неё добавлены все неназначенные кодовые точки.

unique

Пакет unique теперь быстрее, эффективнее и параллельно восстанавливает интернированные значения. В результате приложения, использующие Make, теперь реже сталкиваются с перегрузкой памяти при интернировании большого количества действительно уникальных значений.

Для сбора переданных в Make значений, содержащих дескрипторы, ранее требовалось несколько циклов сборки мусора, пропорциональных глубине цепочки значений дескрипторов. Теперь, если они не используются, они быстро собираются за один цикл.

Порты

Darwin

Как было объявлено в примечаниях к релизу Go 1.24, для Go 1.25 требуется macOS 12 Monterey или более поздняя версия. Поддержка предыдущих версий прекращена.

Windows

Go 1.25 — последний релиз, содержащий неисправный 32-битный порт для Windows/ARM (GOOS=windows GOARCH=arm). Он будет удалён в Go 1.26.

Loong64

Порт linux/loong64 теперь поддерживает детектор гонок, собирая информацию трассировки из кода C с помощью runtime.SetCgoTraceback и связывая программы cgo в режиме внутренней компоновки.

RISC-V

Порт linux/riscv64 теперь поддерживает режим сборки плагина.

Переменная среды GORISCV64 теперь принимает новое значение rva23u64, которое выбирает профиль приложения пользовательского режима RVA23U64.


Читайте также:


купить игрушку gopher

вторник, 4 марта 2025 г.

Релиз Go 1.24

Релиз Go, версия 1.24, выходит через шесть месяцев после Go 1.23. Большинство изменений в нем касаются реализации цепочки инструментов, среды выполнения и библиотек. Как всегда, релиз сохраняет обещание совместимости Go 1. Ожидается, что почти все программы Go продолжат компилироваться и запускаться, как и раньше.

Изменения в языке

Go 1.24 теперь полностью поддерживает псевдонимы универсальных типов: псевдоним типа может быть параметризован как определенный тип. На данный момент эту функцию можно отключить, установив GOEXPERIMENT=noaliastypeparams; но настройка aliastypeparams будет удалена для Go 1.25.

Инструменты

Команда go

Модули Go теперь могут отслеживать зависимости исполняемых файлов с помощью директив инструментов в go.mod. Это устраняет необходимость в предыдущем обходном пути добавления инструментов в виде пустых импортов в файл, который обычно называется «tools.go». Команда go tool теперь может запускать эти инструменты в дополнение к инструментам, поставляемым с дистрибутивом Go.

Новый флаг -tool для go get приводит к добавлению директивы tool в текущий модуль для именованных пакетов в дополнение к добавлению директив require.

Новый меташаблон tool относится ко всем инструментам в текущем модуле. Это можно использовать для их обновления с помощью go get tool или для установки в каталог GOBIN с помощью go install tool.

Исполняемые файлы, созданные go run, и новое поведение go tool теперь кэшируются в кэше сборки Go. Это ускоряет повторные выполнения за счет увеличения кэша.

Команды go build и go install теперь принимают флаг -json, который сообщает о выходных данных сборки и сбоях в виде структурированного вывода JSON на стандартном выводе.

Кроме того, go test -json теперь сообщает о выходных данных сборки и сбоях в формате JSON, чередующемся с результатом теста JSON. Они различаются новыми типами действий, но если они вызывают проблемы в системе интеграции тестов, вы можете вернуться к текстовому выводу сборки с помощью настройки GODEBUG gotestjsonbuildtext=1.

Новая переменная среды GOAUTH обеспечивает гибкий способ аутентификации выборок частных модулей.

Команда go build теперь устанавливает версию основного модуля в скомпилированном двоичном файле на основе тега системы контроля версий и/или фиксации. Суффикс +dirty будет добавлен, если есть незафиксированные изменения. Используйте флаг -buildvcs=false, чтобы исключить информацию о контроле версий из двоичного файла.

Новая настройка GODEBUG toolchaintrace=1 может использоваться для отслеживания процесса выбора цепочки инструментов команды go.

Cgo

Cgo поддерживает новые аннотации для функций C для улучшения производительности во время выполнения. #cgo noescape cFunctionName сообщает компилятору, что память, переданная функции C cFunctionname, не экранируется. #cgo nocallback cFunctionName сообщает компилятору, что функция C cFunctionName не вызывает никаких функций Go.

В настоящее время Cgo отказывается компилировать вызовы функции C, которая имеет несколько несовместимых объявлений. Например, если f объявлена как void f(int) и void f(double), cgo сообщит об ошибке вместо того, чтобы, возможно, сгенерировать некорректную последовательность вызовов для f(0). Новое в этом релизе — лучший детектор для этого состояния ошибки, когда несовместимые объявления появляются в разных файлах.

Objdump

Инструмент objdump теперь поддерживает дизассемблирование на 64-битных LoongArch (GOARCH=loong64), RISC-V (GOARCH=riscv64) и S390X (GOARCH=s390x).

Vet

Новый анализатор тестов сообщает о распространенных ошибках в объявлениях тестов, фаззеров, бенчмарков и примеров в тестовых пакетах, таких как неправильно сформированные имена, неверные подписи или примеры, которые документируют несуществующие идентификаторы. Некоторые из этих ошибок могут привести к тому, что тесты не будут запускаться. Этот анализатор входит в подмножество анализаторов, которые запускаются go test.

Существующий анализатор printf теперь сообщает о диагностике для вызовов формы fmt.Printf(s), где s — это строка непостоянного формата без других аргументов. Такие вызовы почти всегда являются ошибкой, так как значение s может содержать символ %; вместо этого используйте fmt.Print. Эта проверка, как правило, выдает результаты в существующем коде, поэтому применяется только тогда, когда версия языка (указанная директивой go.mod go или комментариями //go:build) не ниже Go 1.24, чтобы избежать сбоев непрерывной интеграции при обновлении до набора инструментов Go 1.24.

Существующий анализатор buildtag теперь выдает диагностику, когда в директиве //go:build есть недопустимое ограничение сборки основной версии Go. Например, //go:build go1.23.1 ссылается на точечный релиз; вместо этого используйте //go:build go1.23.

Существующий анализатор copylock теперь выдает диагностику, когда переменная, объявленная в цикле «for» из 3 предложений, например for i := iter(); done(i); i = next(i) { ... }, содержит sync.Locker, например sync.Mutex. Go 1.22 изменил поведение этих циклов, чтобы создавать новую переменную для каждой итерации, копируя значение из предыдущей итерации; эта операция копирования небезопасна для блокировок.

GOCACHEPROG

Внутренний двоичный и тестовый механизм кэширования cmd/go теперь может быть реализован дочерними процессами, реализующими протокол JSON между инструментом cmd/go и дочерним процессом, названным переменной среды GOCACHEPROG. Ранее это было за GOEXPERIMENT.

Runtime

Несколько улучшений производительности runtime снизили нагрузку на процессор в среднем на 2–3% по набору репрезентативных тестов. Результаты могут различаться в зависимости от приложения. Эти улучшения включают новую встроенную реализацию карты на основе Swiss Tables, более эффективное распределение памяти для небольших объектов и новую реализацию внутреннего мьютекса во время выполнения.

Новую встроенную реализацию карты и новый внутренний мьютекс во время выполнения можно отключить, установив GOEXPERIMENT=noswissmap и GOEXPERIMENT=nospinbitmutex во время сборки соответственно.

Компилятор

Компилятор уже запрещал определять новые методы с типами приемников, которые были сгенерированы cgo, но это ограничение можно было обойти с помощью типа псевдонима. Go 1.24 теперь всегда сообщает об ошибке, если приемник обозначает тип, сгенерированный cgo, как напрямую, так и косвенно (через тип псевдонима).

Компоновщик

Компоновщик теперь по умолчанию генерирует идентификатор сборки GNU (заметка ELF NT_GNU_BUILD_ID) на платформах ELF и UUID (команда загрузки Mach-O LC_UUID) на macOS. Идентификатор сборки или UUID выводится из идентификатора сборки Go. Его можно отключить с помощью флага компоновщика -B none или переопределить с помощью флага компоновщика -B 0xNNNN с указанным пользователем шестнадцатеричным значением.

Bootstrap

Как упоминалось в примечаниях к релизу Go 1.22, Go 1.24 теперь требует Go 1.22.6 или более поздней версии для bootstrap. Ожидается, что Go 1.26 потребует точечный релиз Go 1.24 или более поздней версии для bootstrap.

Стандартная библиотека

Ограниченный каталогом доступ к файловой системе

Новый тип os.Root обеспечивает возможность выполнять операции с файловой системой в определенном каталоге.

Функция os.OpenRoot открывает каталог и возвращает os.Root. Методы os.Root работают в каталоге и не допускают пути, ссылающиеся на местоположения за пределами каталога, включая те, которые следуют по символическим ссылкам из каталога. Методы os.Root отражают большинство операций с файловой системой, доступных в пакете os, включая, например, os.Root.Open, os.Root.Create, os.Root.Mkdir и os.Root.Stat.

Новая функция бенчмарка

Теперь бенчмарки могут использовать более быстрый и менее подверженный ошибкам метод testing.B.Loop для выполнения итераций бенчмарка, например for b.Loop() { ... } вместо типичных структур цикла, включающих b.N, например for range b.N. Это дает два существенных преимущества:

  • Функция бенчмарка будет выполняться ровно один раз за -count, поэтому дорогостоящие шаги настройки и очистки выполняются только один раз.
  • Параметры вызова функции и результаты сохраняются, что не позволяет компилятору полностью оптимизировать тело цикла.

Улучшенные финализаторы

Новая функция runtime.AddCleanup — это механизм финализации, который более гибкий, более эффективный и менее подвержен ошибкам, чем runtime.SetFinalizer. AddCleanup присоединяет функцию очистки к объекту, которая будет запущена, когда объект больше не будет доступен. Однако, в отличие от SetFinalizer, несколько очисток могут быть присоединены к одному объекту, очистки могут быть присоединены к внутренним указателям, очистки обычно не вызывают утечек, когда объекты образуют цикл, и очистки не задерживают освобождение объекта или объектов, на которые он указывает. Новый код должен предпочесть AddCleanup, а не SetFinalizer.

Новый пакет weak

Новый пакет weak предоставляет слабые указатели.

Слабые указатели — это примитив низкого уровня, предоставляемый для создания структур с эффективным использованием памяти, таких как слабые карты для связывания значений, карты канонизации для всего, что не охвачено package unique, и различные виды кэшей. Для поддержки этих вариантов использования этот релиз также предоставляет runtime.AddCleanup и maphash.Comparable.

Новый пакет crypto/mlkem

Новый пакет crypto/mlkem реализует ML-KEM-768 и ML-KEM-1024.

ML-KEM — это постквантовый механизм обмена ключами, ранее известный как Kyber и описанный в FIPS 203.

Новые пакеты crypto/hkdf, crypto/pbkdf2 и crypto/sha3

Новый пакет crypto/hkdf реализует функцию вывода ключа Extract-and-Expand на основе HMAC HKDF, как определено в RFC 5869.

Новый пакет crypto/pbkdf2 реализует функцию вывода ключа на основе пароля PBKDF2, как определено в RFC 8018.

Новый пакет crypto/sha3 реализует хэш-функцию SHA-3 и функции расширяемого вывода SHAKE и cSHAKE, как определено в FIPS 202.

Все три пакета основаны на уже существующих пакетах golang.org/x/crypto/....

Соответствие FIPS 140-3

Этот релиз включает новый набор механизмов для обеспечения соответствия FIPS 140-3.

Go Cryptographic Module — это набор внутренних стандартных пакетов библиотеки, которые прозрачно используются для реализации алгоритмов, одобренных FIPS 140-3. Приложения не требуют никаких изменений для использования Go Cryptographic Module для одобренных алгоритмов.

Новая переменная среды GOFIPS140 может использоваться для выбора версии Go Cryptographic Module для использования в сборке. Новая настройка fips140 GODEBUG может использоваться для включения режима FIPS 140-3 во время выполнения.

Go 1.24 включает Go Cryptographic Module версии v1.0.0, которая в настоящее время проходит тестирование в лаборатории, аккредитованной CMVP.

Новый экспериментальный пакет testing/synctest

Новый экспериментальный пакет testing/synctest обеспечивает поддержку тестирования параллельного кода.

Функция synctest.Run запускает группу горутин в изолированном «пузыре». Внутри пузыря функции пакета времени работают по поддельным часам.

Функция synctest.Wait ждет, пока все горутины в текущем пузыре заблокируются.

Пакет synctest является экспериментальным и должен быть включен путем установки GOEXPERIMENT=synctest во время сборки. API пакета может быть изменен в будущих релизах.

Минорные изменения в библиотеке

archive

Реализации (*Writer).AddFS в archive/zip и archive/tar теперь записывают заголовок каталога для пустого каталога.

bytes

Пакет bytes добавляет несколько функций, которые работают с итераторами:

  • Lines возвращает итератор по строкам, завершающимся символом новой строки, в байтовом срезе.
  • SplitSeq возвращает итератор по всем подсрезам байтового среза, разделенного вокруг разделителя.
  • SplitAfterSeq возвращает итератор по подсрезам байтового среза, разделенного после каждого экземпляра разделителя.
  • FieldsSeq возвращает итератор по подсрезам байтового среза, разделенного вокруг пробельных символов, как определено unicode.IsSpace.
  • FieldsFuncSeq возвращает итератор по подсрезам байтового среза, разделенного вокруг кодовых точек Unicode, удовлетворяющих предикату.

crypto/aes

Значение, возвращаемое NewCipher, больше не реализует методы NewCTR, NewGCM, NewCBCEncrypter и NewCBCDecrypter. Эти методы не были документированы и доступны не на всех архитектурах. Вместо этого значение Block должно передаваться непосредственно соответствующим функциям crypto/cipher. На данный момент crypto/cipher по-прежнему проверяет эти методы в значениях Block, даже если они больше не используются стандартной библиотекой.

crypto/cipher

Новая функция NewGCMWithRandomNonce возвращает AEAD, который реализует AES-GCM, генерируя случайный одноразовый код во время Seal и добавляя его к зашифрованному тексту.

Реализация Stream, возвращаемая NewCTR при использовании с crypto/aes, теперь в несколько раз быстрее на amd64 и arm64.

NewOFB, NewCFBEncrypter и NewCFBDecrypter теперь устарели. Режимы OFB и CFB не аутентифицированы, что обычно позволяет активным атакам манипулировать и восстанавливать открытый текст. Рекомендуется, чтобы приложения использовали режимы AEAD. Если требуется неаутентифицированный режим Stream, используйте NewCTR.

crypto/ecdsa

PrivateKey.Sign теперь создает детерминированную подпись в соответствии с RFC 6979, если случайный источник равен нулю.

crypto/md5

Значение, возвращаемое md5.New, теперь также реализует интерфейс encoding.BinaryAppender.

crypto/rand

Функция Read теперь гарантированно не даст сбой. Она всегда будет возвращать nil в качестве результата ошибки. Если Read столкнется с ошибкой при чтении из Reader, программа безвозвратно завершится сбоем. Обратите внимание, что API платформы, используемые Reader по умолчанию, задокументированы как всегда успешные, поэтому это изменение должно повлиять только на программы, которые переопределяют переменную Reader. Исключением являются ядра Linux до версии 3.17, где Reader по умолчанию все еще открывает /dev/urandom и может дать сбой.

В Linux 6.11 и более поздних версиях Reader теперь использует системный вызов getrandom через vDSO. Это в несколько раз быстрее, особенно для небольших чтений.

В OpenBSD Reader теперь использует arc4random_buf(3).

Новая функция Text может использоваться для генерации криптографически защищенных случайных текстовых строк.

crypto/rsa

GenerateKey теперь возвращает ошибку, если запрашивается ключ длиной менее 1024 бит. Все методы Sign, Verify, Encrypt и Decrypt теперь возвращают ошибку, если используются с ключом длиной менее 1024 бит. Такие ключи небезопасны и не должны использоваться. Настройка GODEBUG rsa1024min=0 восстанавливает старое поведение, но рекомендуется делать это только при необходимости и только в тестах, например, добавляя строку //go:debug rsa1024min=0 в тестовый файл. Новый пример GenerateKey предоставляет простой в использовании стандартный 2048-битный тестовый ключ.

Теперь безопасно и более эффективно вызывать PrivateKey.Precompute перед PrivateKey.Validate. Precompute теперь быстрее при наличии частично заполненных PrecomputedValues, например, при демаршалировании ключа из JSON.

Пакет теперь отклоняет больше недействительных ключей, даже если Validate не вызывается, а GenerateKey может возвращать новые ошибки для сломанных случайных источников. Поля Primes и Precomputed PrivateKey теперь используются и проверяются, даже если некоторые значения отсутствуют.

SignPKCS1v15 и VerifyPKCS1v15 теперь поддерживают SHA-512/224, SHA-512/256 и SHA-3.

GenerateKey теперь использует немного другой метод для генерации закрытой экспоненты (тотиент Кармайкла вместо тотиента Эйлера). Редкие приложения, которые внешне регенерируют ключи только из простых множителей, могут давать разные, но совместимые результаты.

Операции с открытыми и закрытыми ключами теперь выполняются в два раза быстрее на wasm.

crypto/sha1

Значение, возвращаемое sha1.New, теперь также реализует интерфейс encoding.BinaryAppender.

crypto/sha256

Значения, возвращаемые sha256.New и sha256.New224, теперь также реализуют интерфейс encoding.BinaryAppender.

crypto/sha512

Значения, возвращаемые sha512.New, sha512.New384, sha512.New512_224 и sha512.New512_256, теперь также реализуют интерфейс encoding.BinaryAppender.

crypto/subtle

Новая функция WithDataIndependentTiming позволяет пользователю запускать функцию с включенными функциями, специфичными для архитектуры, которые гарантируют, что определенные инструкции являются инвариантными по времени значениями данных. Это можно использовать для того, чтобы убедиться, что код, разработанный для выполнения в постоянном времени, не оптимизирован функциями уровня ЦП, так что он работает в переменном времени. В настоящее время WithDataIndependentTiming использует бит PSTATE.DIT на arm64 и является пустой операцией на всех других архитектурах. GODEBUG настройка dataindependenttiming=1 включает режим DIT для всей программы Go.

Выход XORBytes должен точно перекрываться или не перекрываться входами. Раньше поведение было неопределенным, а теперь XORBytes паникует.

crypto/tls

Сервер TLS теперь поддерживает Encrypted Client Hello (ECH). Эту функцию можно включить, заполнив поле Config.EncryptedClientHelloKeys.

Новый механизм обмена ключами X25519MLKEM768 после квантового режима теперь поддерживается и включается по умолчанию, когда Config.CurvePreferences равен нулю. Параметр GODEBUG tlsmlkem=0 отменяет значение по умолчанию. Это может быть полезно при работе с неисправными серверами TLS, которые некорректно обрабатывают большие записи, вызывая тайм-аут во время рукопожатия.

Поддержка экспериментального обмена ключами X25519Kyber768Draft00 была удалена.

Порядок обмена ключами теперь полностью обрабатывается пакетом crypto/tls. Порядок Config.CurvePreferences теперь игнорируется, а содержимое используется только для определения того, какие обмены ключами следует включить при заполнении поля.

Новое поле ClientHelloInfo.Extensions содержит идентификаторы расширений, полученных в сообщении Client Hello. Это может быть полезно для идентификации клиентов TLS.

crypto/x509

Настройка x509sha1 GODEBUG была удалена. Certificate.Verify больше не поддерживает подписи на основе SHA-1.

OID теперь реализует интерфейсы encoding.BinaryAppender и encoding.TextAppender.

Поле политик сертификатов по умолчанию изменилось с Certificate.PolicyIdentifiers на Certificate.Policies. При анализе сертификатов будут заполнены оба поля, но при создании сертификатов политики теперь будут взяты из поля Certificate.Policies вместо поля Certificate.PolicyIdentifiers. Это изменение можно отменить с помощью настройки GODEBUG x509usepolicies=0.

CreateCertificate теперь будет генерировать серийный номер с использованием метода, соответствующего RFC 5280, при передаче шаблона с нулевым полем Certificate.SerialNumber вместо сбоя.

Certificate.Verify теперь поддерживает проверку политики, как определено в RFC 5280 и RFC 9618. Новое поле VerifyOptions.CertificatePolicies может быть установлено на приемлемый набор OID политики. Из Certificate.Verify будут возвращены только цепочки сертификатов с допустимыми графами политики.

MarshalPKCS8PrivateKey теперь возвращает ошибку вместо маршалинга недействительного ключа RSA. (MarshalPKCS1PrivateKey не возвращает ошибку, и его поведение при предоставлении недействительных ключей по-прежнему не определено.)

ParsePKCS1PrivateKey и ParsePKCS8PrivateKey теперь используют и проверяют закодированные значения CRT, поэтому могут отклонять недействительные ключи RSA, которые были приняты ранее. Используйте настройку GODEBUG x509rsacrt=0, чтобы вернуться к пересчету значений CRT.

debug/elf

Пакет debug/elf добавляет поддержку обработки версий символов в динамических файлах ELF (исполняемый и связываемый формат). Новый метод File.DynamicVersions возвращает список динамических версий, определенных в файле ELF. Новый метод File.DynamicVersionNeeds возвращает список динамических версий, требуемых этим файлом ELF, которые определены в других объектах ELF. Наконец, новые поля Symbol.HasVersion и Symbol.VersionIndex указывают версию символа.

encoding

Два новых интерфейса, TextAppender и BinaryAppender, были введены для добавления текстового или двоичного представления объекта к байтовому срезу. Эти интерфейсы предоставляют ту же функциональность, что и TextMarshaler и BinaryMarshaler, но вместо того, чтобы каждый раз выделять новый срез, они добавляют данные непосредственно к существующему срезу. Эти интерфейсы теперь реализуются стандартными библиотечными типами, которые уже реализовали TextMarshaler и/или BinaryMarshaler.

encoding/json

При маршалинге поле структуры с новой опцией omitzero в теге поля структуры будет опущено, если его значение равно нулю. Если тип поля имеет метод IsZero() bool, он будет использоваться для определения, равно ли значение нулю. В противном случае значение равно нулю, если это нулевое значение для его типа. Тег поля omitzero более понятен и менее подвержен ошибкам, чем omitempty, когда намерение состоит в том, чтобы опустить нулевые значения. В частности, в отличие от omitempty, omitzero опускает нулевые значения time.Time, что является распространенным источником проблем.

Если указаны и omitempty, и omitzero, поле будет опущено, если значение либо пустое, либо нулевое (или оба).

UnmarshalTypeError.Field теперь включает встроенные структуры для предоставления более подробных сообщений об ошибках.

go/types

Все структуры данных go/types, которые предоставляют последовательности с помощью пары методов, таких как Len() int и At(int) T, теперь также имеют методы, которые возвращают итераторы, что позволяет упростить код, например:

params := fn.Type.(*types.Signature).Params()
for i := 0; i < params.Len(); i++ {
    use(params.At(i))
}

к виду:

for param := range fn.Signature().Params().Variables() {
    use(param)
}

Добавлены методы: Interface.EmbeddedTypes, Interface.ExplicitMethods, Interface.Methods, MethodSet.Methods, Named.Methods, Scope.Children, Struct.Fields, Tuple.Variables, TypeList.Types, TypeParamList.TypeParams, Union.Terms.

hash/adler32

Значение, возвращаемое New, теперь также реализует интерфейс encoding.BinaryAppender.

hash/crc32

Значения, возвращаемые New и NewIEEE, теперь также реализуют интерфейс encoding.BinaryAppender.

hash/crc64

Значение, возвращаемое New, теперь также реализует интерфейс encoding.BinaryAppender.

hash/fnv

Значения, возвращаемые New32, New32a, New64, New64a, New128 и New128a, теперь также реализуют интерфейс encoding.BinaryAppender.

hash/maphash

Новые функции Comparable и WriteComparable могут вычислять хеш любого сопоставимого значения. Они позволяют хешировать все, что может использоваться в качестве ключа карты Go.

log/slog

Новый DiscardHandler — это обработчик, который никогда не включается и всегда отбрасывает свой вывод.

Level и LevelVar теперь реализуют интерфейс encoding.TextAppender.

math/big

Float, Int и Rat теперь реализуют интерфейс encoding.TextAppender.

math/rand

Вызовы устаревшей функции Seed верхнего уровня больше не имеют никакого эффекта. Чтобы восстановить старое поведение, используйте настройку GODEBUG randseednop=0.

math/rand/v2

ChaCha8 и PCG теперь реализуют интерфейс encoding.BinaryAppender.

net

ListenConfig теперь использует MPTCP по умолчанию в системах, где он поддерживается (в настоящее время только в Linux).

IP теперь реализует интерфейс encoding.TextAppender.

net/http

Ограничение Transport на информационные ответы 1xx, полученные в ответ на запрос, изменилось. Ранее он прерывал запрос и возвращал ошибку после получения более 5 ответов 1xx. Теперь он возвращает ошибку, если общий размер всех ответов 1xx превышает настройку конфигурации Transport.MaxResponseHeaderBytes.

Кроме того, когда запрос имеет хук трассировки net/http/httptrace.ClientTrace.Got1xxResponse, теперь нет ограничений на общее количество ответов 1xx. Хук Got1xxResponse может вернуть ошибку, чтобы прервать запрос.

Transport и Server теперь имеют поле HTTP2, которое позволяет настраивать параметры протокола HTTP/2.

Новые поля Server.Protocols и Transport.Protocols предоставляют простой способ настройки протоколов HTTP, используемых сервером или клиентом.

Сервер и клиент могут быть настроены для поддержки незашифрованных соединений HTTP/2.

Когда Server.Protocols содержит UnencryptedHTTP2, сервер будет принимать соединения HTTP/2 на незашифрованных портах. Сервер может принимать как HTTP/1, так и незашифрованный HTTP/2 на одном и том же порту.

Если Transport.Protocols содержит UnencryptedHTTP2 и не содержит HTTP1, транспорт будет использовать незашифрованный HTTP/2 для http:// URL-адресов. Если транспорт настроен на использование как HTTP/1, так и незашифрованного HTTP/2, он будет использовать HTTP/1.

Поддержка незашифрованного HTTP/2 использует «HTTP/2 с предшествующими знаниями» (RFC 9113, раздел 3.3). Устаревший заголовок «Upgrade: h2c» не поддерживается.

net/netip

Addr, AddrPort и Prefix теперь реализуют интерфейсы encoding.BinaryAppender и encoding.TextAppender.

net/url

URL теперь также реализует интерфейс encoding.BinaryAppender.

os/user

В Windows Current теперь можно использовать в Windows Nano Server. Реализация была обновлена, чтобы избежать использования функций из библиотеки NetApi32, которая недоступна в Nano Server.

В Windows Current, Lookup и LookupId теперь поддерживают следующие встроенные учетные записи пользователей служб:

  • NT AUTHORITY\SYSTEM
  • NT AUTHORITY\LOCAL SERVICE
  • NT AUTHORITY\NETWORK SERVICE

В Windows Current стал значительно быстрее, когда текущий пользователь присоединен к медленному домену, что является обычным случаем для многих корпоративных пользователей. Производительность новой реализации теперь составляет порядка миллисекунд по сравнению с предыдущей реализацией, которая могла занять несколько секунд или даже минут.

В Windows Current теперь возвращает пользователя-владельца процесса, когда текущий поток выдает себя за другого пользователя. Ранее он возвращал ошибку.

regexp

Теперь Regexp реализует интерфейс encoding.TextAppender.

runtime

Функция GOROOT теперь устарела. В новом коде предпочтительнее использовать системный путь для поиска двоичного файла «go» и использовать go env GOROOT для поиска его GOROOT.

strings

Пакет strings добавляет несколько функций, которые работают с итераторами:

  • Lines возвращает итератор по строкам, завершающимся символом новой строки, в строке.
  • SplitSeq возвращает итератор по всем подстрокам строки, разделенной по разделителю.
  • SplitAfterSeq возвращает итератор по подстрокам строки, разделенной после каждого экземпляра разделителя.
  • FieldsSeq возвращает итератор по подстрокам строки, разделенной по пробельным символам, как определено в unicode.IsSpace.
  • FieldsFuncSeq возвращает итератор по подстрокам строки, разделенной вокруг последовательностей кодовых точек Unicode, удовлетворяющих предикату.

sync

Реализация sync.Map была изменена, что повысило производительность, особенно для изменений карт. Например, изменения непересекающихся наборов ключей с гораздо меньшей вероятностью будут конфликтовать на больших картах, и больше не требуется время наращивания для достижения низкоконкурентных загрузок из карты.

Если у вас возникнут какие-либо проблемы, установите GOEXPERIMENT=nosynchashtriemap во время сборки, чтобы вернуться к старой реализации, и сообщите о проблеме.

testing

Новые методы T.Context и B.Context возвращают контекст, который отменяется после завершения теста и до запуска функций очистки теста.

Новые методы T.Chdir и B.Chdir можно использовать для изменения рабочего каталога на время теста или бенчмарка.

text/template

Теперь шаблоны поддерживают range-over-func и range-over-int.

time

Теперь Time реализует интерфейсы encoding.BinaryAppender и encoding.TextAppender.

Порты

Linux

Как было объявлено в примечаниях к релизу Go 1.23, для Go 1.24 требуется ядро Linux версии 3.2 или более поздней.

Darwin

Go 1.24 — последний релиз, который будет работать на macOS 11 Big Sur. Для Go 1.25 потребуется macOS 12 Monterey или более поздней версии.

WebAssembly

Директива компилятора go:wasmexport добавлена для программ Go для экспорта функций на хост WebAssembly.

В WebAssembly System Interface Preview 1 (GOOS=wasip1 GOARCH=wasm) Go 1.24 поддерживает сборку программы Go в качестве реактора/библиотеки, указав флаг сборки -buildmode=c-shared.

Теперь больше типов разрешено в качестве типов аргументов или результатов для функций go:wasmimport. В частности, разрешены bool, string, uintptr и указатели на определенные типы, а также 32- и 64-битные целые и float типы и unsafe.Pointer, которые уже разрешены. Эти типы также разрешены в качестве типов аргументов или результатов для функций go:wasmexport.

Файлы поддержки для WebAssembly были перемещены в lib/wasm из misc/wasm.

Начальный размер памяти значительно уменьшен, особенно для небольших приложений WebAssembly.

Windows

32-битный порт windows/arm (GOOS=windows GOARCH=arm) отмечен как сломанный.


Читайте также:


купить игрушку gopher

пятница, 18 октября 2024 г.

Как итерировать по символам в строках Go

В Go итерация по строке по ее символам (или знакам) может быть выполнена несколькими различными способами.

Использование цикла for...range

Наиболее распространенный и идиоматический способ итерации по строке в Go — использование цикла for...range. Этот метод правильно обрабатывает символы Unicode, рассматривая каждый символ как руну (что является псевдонимом для int32). Вот пример:

package main

import "fmt"

func main() {
    str := "Hello, 世界" // Строка с символами ASCII и не-ASCII

    for index, char := range str {
        fmt.Printf("Index: %d, Character: %c\n", index, char)
    }
}

Вывод:

Index: 0, Character: H
Index: 1, Character: e
Index: 2, Character: l
Index: 3, Character: l
Index: 4, Character: o
Index: 5, Character: ,
Index: 6, Character:
Index: 7, Character: 世
Index: 8, Character: 界

Использование стандартного цикла for с рунами

Если вы предпочитаете использовать традиционный цикл for, вы можете преобразовать строку в срез рун. Это позволяет вам перебирать каждый символ, сохраняя правильное представление символов Unicode:

package main

import "fmt"

func main() {
    str := "Hello, 世界"
    runes := []rune(str) // Преобразовать строку в срез рун

    for i := 0; i < len(runes); i++ {
        fmt.Printf("Rune %d is '%c'\n", i, runes[i])
    }
}

Вывод:

Rune 0 is 'H'
Rune 1 is 'e'
Rune 2 is 'l'
Rune 3 is 'l'
Rune 4 is 'o'
Rune 5 is ','
Rune 6 is ' '
Rune 7 is '世'
Rune 8 is '界'

Использование метода strings.Split

Другой подход — использовать метод strings.Split для разделения строки на отдельные символы. Однако этот метод может быть не таким эффективным или идиоматичным, как предыдущие методы:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello, 世界"
    chars := strings.Split(str, "") // Разделить строку на отдельные символы

    for _, char := range chars {
        fmt.Printf("Character: %s\n", char)
    }
}

Вывод:

Character: H
Character: e
Character: l
Character: l
Character: o
Character: ,
Character:
Character: 世
Character: 界

В Go предпочтительным способом перебора строк по символам является использование цикла for...range, поскольку он автоматически обрабатывает кодировку UTF-8 и обеспечивает простой способ доступа к каждому символу как к руне. В качестве альтернативы преобразование строки в срез рун обеспечивает больший контроль с помощью традиционной индексации. Метод strings.Split также можно использовать, но он менее эффективен для этой цели. Понимание этих методов поможет вам эффективно работать со строками в Go.


Читайте также:


Строки как тип данных в Go

В Go (Golang) строка — это фундаментальный тип данных, используемый для представления последовательности символов. Он широко используется для обработки текста и необходим для различных задач программирования.

Характеристики строк в Go

Неизменяемость - после создания строки ее значение не может быть изменено. Любая операция, которая, как кажется, изменяет строку, на самом деле создает новую строку. Эта неизменяемость помогает оптимизировать использование памяти и обеспечить безопасность потоков.

Кодировка UTF-8 - строки в Go по умолчанию кодируются в UTF-8, что позволяет им представлять широкий спектр символов из разных языков. Каждый символ может занимать один или несколько байтов, что делает его гибким для интернационализации.

Срез байтов только для чтения - строку можно рассматривать как срез байтов только для чтения. Это означает, что хотя вы можете получить доступ к байтам, составляющим строку, вы не можете изменять их напрямую.

Создание строк

Строки в Go можно создавать с помощью двойных кавычек для интерпретируемых литералов или обратных кавычек для необработанных литералов.

Интерпретируемые литералы - поддерживают escape-последовательности (например, "\n" для новой строки).

str1 := "Hello, World!"

Необработанные литералы - заключены в обратные кавычки, они не поддерживают escape-последовательности и могут охватывать несколько строк.

str2 := `Это необработанный строковый литерал,
который может охватывать несколько строк.`

Операции и функции со строками

Go предоставляет несколько встроенных функций и методов для работы со строками, в основном через пакет strings. Некоторые распространенные операции включают:

Длина - используйте len() для получения количества байтов в строке.

length := len(str1) // Возвращает длину str1

Конкатенация - строки можно объединять с помощью оператора +.

combined := str1 + " " + str2

Подстрока - можно извлекать подстроки с помощью синтаксиса среза.

sub := str1[0:5] // "Hello"

Поиск и замена - функции, такие как strings.Contains(), strings.Replace() и strings.Index(), помогают находить подстроки или заменять части строк.

Пример кода

Вот простой пример, демонстрирующий создание строки и некоторые базовые операции:

package main

import (
    "fmt"
    "strings"
)

func main() {
    // Создание строк
    greeting := "Hello"
    name := "World"

    // Объединение строк
    message := greeting + ", " + name + "!"
    fmt.Println(message) // Вывод: Hello, World!

    // Проверка длины
    fmt.Println("Длина:", len(message)) // Вывод: Длина: 13

    // Поиск подстроки
    index := strings.Index(message, "World")
    fmt.Println("Индекс 'World':", index) // Вывод: Индекс 'World': 7

    // Замена подстроки
    newMessage := strings.Replace(message, "World", "Gopher", 1)
    fmt.Println(newMessage) // Вывод: Hello, Gopher!
}

Строки в Go — мощный, но простой в использовании инструмент, предоставляющий основные функции для обработки текста, обеспечивая при этом эффективность за счет неизменяемости и кодировки UTF-8. Понимание того, как эффективно работать со строками, имеет решающее значение для любого разработчика Go, поскольку они составляют основу большинства приложений, работающих с текстовыми данными.


Читайте также:


пятница, 27 сентября 2024 г.

Где в памяти располагаются переменные в Golang

В Go переменной соответствует область памяти, которая может располагаться либо на стеке, либо в куче, в зависимости от типа данных этой переменной. Рассмотрим оба случая:

На стеке

Переменные размещаются на стеке (stack), когда они локальны для функции или метода. Например, если переменная объявлена внутри функции:

func main() {
    var myVar string // Переменная 'myVar' будет находиться на стеке
}

Стек используется для хранения локальных переменных, аргументов функций и временных данных, таких как результаты выражений. Когда функция завершает выполнение, все данные на стеке автоматически освобождаются.

В куче (heap)

Переменная будет находиться в куче, если она является глобальной или создана с использованием ключевого слова new.

Глобальные переменные

package main

var myVar string // Переменная 'myVar' будет находиться в куче

func main() {}

Глобальная переменная находится в куче на протяжении всего времени жизни программы. Куча используется для больших объемов данных, которые могут существовать дольше, чем текущий вызов функции.

Создание переменной через new

package main

import "fmt"

func main() {
    var myVar *string = new(string) // Переменная 'myVar' будет находиться в куче
    fmt.Println(*myVar)             // Результат будет nil
    
    *myVar = "Hello, World!"        // Заполнение значения по адресу переменной
    fmt.Println(*myVar)             // Вывод: Hello, World!
}

При использовании оператора new, создается новая область памяти в куче и возвращается ее адрес.

Таким образом, чтобы определить, где именно в памяти находится переменная, нужно проанализировать её использование в коде:

  • Если переменная локальна для функции, то она будет находиться на стеке.
  • Если она является глобальной, то будет находиться в куче.
  • Если использовалось ключевое слово new, то она также будет находиться в куче.

Читайте также:


Как Golang работает с памятью

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

Автоматическое управление памятью

Компилятор Go автоматически выделяет и освобождает память для переменных и структур данных. Когда переменная выходит из области видимости, ее память автоматически освобождается за счет работы сборщика мусора. Это упрощает написание программ и уменьшает количество ошибок, связанных с утечками памяти.

Память, выделенная в стеке

Локальные переменные и параметры функций выделяются в стеке. Стек растет вверх по мере создания новых переменных, но когда функция возвращается, все локальные данные удаляются, что обеспечивает их автоматическое освобождение.

Динамическая память (куча, heap)

Переменные, созданные с помощью оператора new, размещаются в куче. Куча используется для хранения объектов, которые должны существовать дольше одной функции. Управление памятью в куче осуществляется через сборщик мусора, который периодически сканирует память и освобождает объекты, на которые больше нет ссылок.

Сборка мусора

Сборщик мусора в Go является многопоточным и может работать параллельно с другими процессами программы. Он не блокирует выполнение других потоков и не прерывает работу приложения. Это позволяет Go эффективно управлять памятью даже в многопоточных приложениях.

Безопасность памяти

Поскольку Go сам не управляет памятью напрямую, это снижает риск утечек памяти и других проблем, связанных с некорректной работой с памятью.

Высокая производительность

Так как Go использует механизмы операционной системы для управления памятью и сборки мусора, это позволяет добиться высокой производительности при работе с большими объемами данных.


Читайте также:


среда, 28 августа 2024 г.

Релиз Go 1.23

Релиз Go 1.23, выходит через шесть месяцев после Go 1.22. Большинство изменений в нем касаются реализации цепочки инструментов, среды выполнения и библиотек. Как всегда, релиз сохраняет обещание совместимости Go 1. Ожидается, что почти все программы Go продолжат компилироваться и запускаться, как и прежде.

Изменения в языке

Go 1.23 делает эксперимент (Go 1.22) "range-over-func" частью языка. "range" в цикле "for-range" теперь принимает функции итератора следующих типов

func(func() bool)
func(func(K) bool)
func(func(K, V) bool)

как выражения диапазона. Вызовы функции аргумента итератора создают значения итерации для цикла "for-range".

Go 1.23 включает предварительную поддержку псевдонимов универсальных типов. Создание цепочки инструментов с GOEXPERIMENT=aliastypeparams включает эту функцию в пакете. (Использование универсальных псевдонимов за пределами границ пакета пока не поддерживается.)

Инструменты

Телеметрия

Начиная с Go 1.23, цепочка инструментов Go может собирать статистику использования и поломок, которая помогает команде Go понять, как используется цепочка инструментов Go и насколько хорошо она работает. Эта статистика называется телеметрией Go.

Телеметрия Go — это включаемая по настройке система, управляемая командой go telemetry. По умолчанию программы цепочки инструментов собирают статистику в файлах счетчиков, которые можно проверять локально, но в остальном не используются (локальная телеметрия go).

Чтобы помочь разработчикам языка поддерживать хорошую работу Go и понимать использование Go рассмотрите возможность включения телеметрии Go, запустив go telemetry on. В этом режиме анонимные отчеты счетчиков еженедельно загружаются на telemetry.go.dev, где они объединяются в графики и также становятся доступными для загрузки любыми участниками Go или пользователями, желающими проанализировать данные.

Команда Go

Установка переменной среды GOROOT_FINAL больше не имеет эффекта. Дистрибутивы, которые устанавливают команду go в местоположение, отличное от $GOROOT/bin/go, должны устанавливать символическую ссылку вместо перемещения или копирования двоичного файла go.

Новый флаг go env -changed заставляет команду печатать только те настройки, эффективное значение которых отличается от значения по умолчанию, которое было бы получено в пустой среде без предварительного использования флага -w.

Новый флаг go mod tidy -diff заставляет команду не изменять файлы, а вместо этого печатать необходимые изменения в виде единого diff. Он завершается с ненулевым кодом, если требуются обновления.

Команда go list -m -json теперь включает новые поля Sum и GoModSum. Это похоже на существующее поведение команды go mod download -json.

Новая директива godebug в go.mod и go.work объявляет настройку GODEBUG для применения к используемому рабочему модулю или рабочему пространству.

Vet

Подкоманда go vet теперь включает анализатор stdversion, который помечает ссылки на символы, которые слишком новые для версии Go, действующей в ссылающемся файле. (Эффективная версия определяется директивой go в файле go.mod, включающем файл, и любыми ограничениями //go:build в файле.)

Например, она выдаст диагностику для ссылки на функцию reflect.TypeFor (введенную в go1.22) из ​​файла в модуле, файл go.mod которого указывает go 1.21.

Cgo

cmd/cgo поддерживает новый флаг -ldflags для передачи флагов компоновщику C. Команда go использует его автоматически, избегая ошибок “argument list too long” ("слишком длинный список аргументов") с очень большим CGO_LDFLAGS.

Trace

Инструмент трассировки теперь лучше переносит частично поврежденные трассировки, пытаясь восстановить те данные трассировки, которые он может. Эта функция особенно полезна при просмотре трассировки, собранной во время сбоя программы, поскольку данные трассировки, приведшие к сбою, теперь можно восстановить в большинстве случаев.

Среда выполнения

Трассировка, напечатанная средой выполнения после необработанной паники или другой фатальной ошибки, теперь отступает вторую и последующие строки сообщения об ошибке (например, аргумент паники) на одну табуляцию, чтобы ее можно было однозначно отличить от трассировки стека первой горутины.

Компилятор

Накладные расходы на сборку с Profile Guided Optimization были значительно сокращены. Ранее большие сборки могли увидеть увеличение времени сборки на 100%+ при включении PGO. В Go 1.23 накладные расходы должны быть в однозначных процентах.

Компилятор в Go 1.23 теперь может перекрывать слоты кадра стека локальных переменных, доступных в непересекающихся областях функции, что снижает использование стека для приложений Go.

Для 386 и amd64 компилятор будет использовать информацию из PGO для выравнивания определенных горячих блоков в циклах. Это повышает производительность еще на 1-1,5% за счет дополнительных 0,1% размера текста и двоичного кода. В настоящее время это реализовано только на 386 и amd64, поскольку не показало улучшения на других платформах. Выравнивание горячих блоков можно отключить с помощью -gcflags=[<packages>=]-d=alignhot=0.

Компоновщик

Теперь компоновщик запрещает использовать директиву //go:linkname для ссылки на внутренние символы в стандартной библиотеке (включая среду выполнения), которые не отмечены //go:linkname в своих определениях. Аналогично компоновщик запрещает ссылки на такие символы из ассемблерного кода. Для обратной совместимости существующие использования //go:linkname, найденные в большом количестве открытого исходного кода, остаются поддерживаемыми. Любые новые ссылки на внутренние символы стандартной библиотеки будут запрещены.

Флаг командной строки компоновщика -checklinkname=0 можно использовать для отключения этой проверки в целях отладки и экспериментирования.

При сборке динамически связанного двоичного файла ELF (включая двоичный файл PIE) новый флаг -bindnow включает немедленное связывание функций.

Стандартная библиотека

Изменения таймера

Go 1.23 вносит два существенных изменения в реализацию time.Timer и time.Ticker.

Во-первых, таймеры и тикеры, на которые больше не ссылается программа, немедленно становятся доступными для сборки мусора, даже если их методы Stop не были вызваны. Более ранние версии Go не собирали неостановленные таймеры до тех пор, пока они не сработают, и никогда не собирали неостановленные тикеры.

Во-вторых, канал таймера, связанный с таймером или тикером, теперь не буферизован, с емкостью 0. Основной эффект этого изменения заключается в том, что Go теперь гарантирует, что для любого вызова метода Reset или Stop никакие устаревшие значения, подготовленные до этого вызова, не будут отправлены или получены после вызова. Более ранние версии Go использовали каналы с одноэлементным буфером, что затрудняло правильное использование Reset и Stop. Видимым эффектом этого изменения является то, что len и cap каналов таймера теперь возвращают 0 вместо 1, что может повлиять на программы, которые опрашивают длину, чтобы решить, будет ли прием на канале таймера успешным. Такой код должен использовать неблокируемый прием вместо этого.

Эти новые поведения включаются только тогда, когда основная программа Go находится в модуле со строкой go в go.mod, использующей Go 1.23.0 или более позднюю версию. Когда Go 1.23 собирает старые программы, старые поведения остаются в силе. Новая настройка GODEBUG asynctimerchan=1 может использоваться для возврата к асинхронному поведению канала, даже если программа называет Go 1.23.0 или более позднюю версию в своем файле go.mod.

Новый пакет unique

Новый пакет unique предоставляет возможности для канонизации значений (например, "интернирование" или "хэш-консинг").

Любое значение сопоставимого типа может быть канонизировано с помощью новой функции Make[T], которая создает ссылку на каноническую копию значения в форме Handle[T]. Два Handle[T] равны тогда и только тогда, когда значения, используемые для создания дескрипторов, равны, что позволяет программам дедуплицировать значения и уменьшать свой объем памяти. Сравнение двух значений Handle[T] эффективно, сводясь к простому сравнению указателей.

Итераторы

Новый пакет iter предоставляет основные определения для работы с пользовательскими итераторами.

Пакет slices добавляет несколько функций, которые работают с итераторами:

  • All возвращает итератор по индексам и значениям среза.
  • Values возвращает итератор по элементам среза.
  • Backward возвращает итератор, который проходит по срезу в обратном направлении.
  • Collect собирает значения из итератора в новый срез.
  • AppendSeq добавляет значения из итератора в существующий срез.
  • Sorted собирает значения из итератора в новый срез, а затем сортирует срез.
  • SortedFunc похож на Sorted, но с функцией сравнения.
  • SortedStableFunc похож на SortFunc, но использует стабильный алгоритм сортировки.
  • Chunk возвращает итератор по последовательным подсрезам до n элементов среза.

Пакет maps добавляет несколько функций, которые работают с итераторами:

  • All возвращает итератор по парам ключ-значение из карты.
  • Keys возвращает итератор по ключам в карте.
  • Values возвращает итератор по значениям в карте.
  • Insert добавляет пары ключ-значение из итератора в существующую карту.
  • Collect собирает пары ключ-значение из итератора в новую карту и возвращает ее.

Новый пакет structs

Новый пакет structs предоставляет типы для полей структур, которые изменяют свойства содержащего типа структуры, такие как макет памяти.

В этом релизе единственным таким типом является HostLayout, который указывает, что структура с полем этого типа имеет макет, который соответствует ожиданиям платформы хоста. HostLayout следует использовать в типах, которые передаются, возвращаются или доступны через указатель, переданный в/из API хоста. Без этого маркера порядок макета структур не гарантируется спецификацией языка, хотя с версии Go 1.23 макеты хоста и языка совпадают.

Незначительные изменения в библиотеке

archive/tar

Если аргумент FileInfoHeader реализует новый интерфейс FileInfoNames, то методы интерфейса будут использоваться для установки Uname/Gname заголовка файла. Это позволяет приложениям переопределять зависящий от системы поиск Uname/Gname.

crypto/tls

Клиент TLS теперь поддерживает черновую спецификацию Encrypted Client Hello. Эту функцию можно включить, установив поле Config.EncryptedClientHelloConfigList в закодированный ECHConfigList для хоста, к которому выполняется подключение.

Тип QUICConn, используемый реализациями QUIC, включает новые события, сообщающие о состоянии возобновления сеанса, и предоставляет способ для уровня QUIC добавлять данные в билеты сеанса и записи кэша сеанса.

Наборы шифров 3DES были удалены из списка по умолчанию, используемого, когда Config.CipherSuites равен нулю. Значение по умолчанию можно вернуть, добавив tls3des=1 в переменную среды GODEBUG.

Экспериментальный постквантовый механизм обмена ключами X25519Kyber768Draft00 теперь включен по умолчанию, когда Config.CurvePreferences равен нулю. Значение по умолчанию можно вернуть, добавив tlskyber=0 в переменную среды GODEBUG.

В версии 1.23 поведение X509KeyPair и LoadX509KeyPair изменено для заполнения поля Certificate.Leaf возвращаемого сертификата. Для этого поведения добавлен новый параметр x509keypairleaf GODEBUG.

crypto/x509

CreateCertificateRequest теперь правильно поддерживает алгоритмы подписи RSA-PSS.

CreateCertificateRequest и CreateRevocationList теперь проверяют сгенерированную подпись с помощью открытого ключа подписчика. Если подпись недействительна, возвращается ошибка. Это поведение CreateCertificate с версии Go 1.16.

Параметр x509sha1 GODEBUG будет удален в следующем основном релизе Go (Go 1.24). Это будет означать, что crypto/x509 больше не будет поддерживать проверку подписей на сертификатах, использующих алгоритмы подписи на основе SHA-1.

Новая функция ParseOID анализирует строку идентификатора объекта ASN.1, закодированную точками. Тип OID теперь реализует интерфейсы encoding.BinaryMarshaler, encoding.BinaryUnmarshaler, encoding.TextMarshaler, encoding.TextUnmarshaler.

database/sql

Ошибки, возвращаемые реализациями driver.Valuer, теперь заключены в оболочку для улучшенной обработки ошибок во время таких операций, как DB.Query, DB.Exec и DB.QueryRow.

debug/elf

Пакет debug/elf теперь определяет PT_OPENBSD_NOBTCFI. Этот ProgType используется для отключения принудительного применения Branch Tracking Control Flow Integrity (BTCFI) в двоичных файлах OpenBSD.

Теперь определяет константы типа символа STT_RELC, STT_SRELC и STT_GNU_IFUNC.

coding/binary

Новые функции Encode и Decode являются эквивалентами байтовых срезов Read и Write. Append позволяет объединять несколько данных в один байтовый срез.

go/ast

Новая функция Preorder возвращает удобный итератор по всем узлам синтаксического дерева.

go/types

Тип Func, представляющий символ функции или метода, теперь имеет метод Func.Signature, который возвращает тип функции, который всегда является Signature.

Тип Alias теперь имеет метод Rhs, который возвращает тип в правой части его объявления: учитывая тип A = B, Rhs A равен B.

Были добавлены методы Alias.Origin, Alias.SetTypeParams, Alias.TypeParams и Alias.TypeArgs. Они необходимы для типов-псевдонимов.

По умолчанию go/types теперь создает узлы типа Alias ​​для псевдонимов типов. Это поведение можно контролировать с помощью флага GODEBUG gotypesalias. Его значение по умолчанию изменилось с 0 в Go 1.22 на 1 в Go 1.23.

math/rand/v2

Были добавлены функция Uint и метод Rand.Uint. Они были непреднамеренно исключены из Go 1.22.

Новый метод ChaCha8.Read реализует интерфейс io.Reader.

net

Новый тип KeepAliveConfig позволяет настраивать параметры поддержки активности для TCP-соединений с помощью нового метода TCPConn.SetKeepAliveConfig и новых полей KeepAliveConfig для Dialer и ListenConfig.

Тип DNSError теперь оборачивает ошибки, вызванные тайм-аутами или отменой. Например, error.Is(someDNSErr, context.DeadlineExceedeed) теперь будет сообщать, была ли ошибка DNS вызвана тайм-аутом.

Новый параметр GODEBUG netedns0=0 отключает отправку дополнительных заголовков EDNS0 в запросах DNS, поскольку, как сообщается, они нарушают работу DNS-сервера на некоторых модемах.

net/http

Cookie теперь сохраняет двойные кавычки вокруг значения cookie. Новое поле Cookie.Quoted указывает, было ли Cookie.Value изначально закавычено.

Новый метод Request.CookiesNamed извлекает все cookie, соответствующие заданному имени.

Новое поле Cookie.Partitioned идентифицирует файлы cookie с атрибутом Partitioned.

Шаблоны, используемые ServeMux, теперь допускают один или несколько пробелов или табуляций после имени метода. Ранее разрешался только один пробел.

Новая функция ParseCookie анализирует значение заголовка Cookie и возвращает все файлы cookie, которые были установлены в нем. Поскольку одно и то же имя файла cookie может встречаться несколько раз, возвращаемые значения могут содержать более одного значения для данного ключа.

Новая функция ParseSetCookie анализирует значение заголовка Set-Cookie и возвращает файл cookie. Она возвращает ошибку при синтаксической ошибке.

ServeContent, ServeFile и ServeFileFS теперь удаляют заголовки Cache-Control, Content-Encoding, Etag и Last-Modified при обслуживании ошибки. Эти заголовки обычно применяются к содержимому без ошибок, но не к тексту ошибок.

Промежуточное ПО, которое оборачивает ResponseWriter и применяет кодирование "на лету", например Content-Encoding: gzip, не будет работать после этого изменения. Предыдущее поведение ServeContent, ServeFile и ServeFileFS можно восстановить, установив GODEBUG=httpservecontentkeepheaders=1.

Обратите внимание, что промежуточное ПО, которое изменяет размер обслуживаемого контента (например, сжимая его), уже не работает должным образом, когда ServeContent обрабатывает запрос Range. Сжатие "на лету" должно использовать заголовок Transfer-Encoding вместо Content-Encoding.

Для входящих запросов новое поле Request.Pattern содержит шаблон ServeMux (если есть), который соответствует запросу. Это поле не задается, если задано GODEBUG=httpmuxgo121=1.

net/http/httptest

Новый метод NewRequestWithContext создает входящий запрос с context.Context.

net/netip

В Go 1.22 и более ранних версиях использование reflect.DeepEqual для сравнения Addr, содержащего адрес IPv4, с Addr, содержащим форму IPv6, сопоставленную с IPv4, неправильно возвращало значение true, даже если значения Addr отличались при сравнении с == или Addr.Compare. Теперь эта ошибка исправлена, и все три подхода теперь выдают одинаковый результат.

os

Функция Stat теперь устанавливает бит ModeSocket для файлов, которые являются сокетами Unix в Windows. Эти файлы идентифицируются по тегу повторной обработки, установленному на IO_REPARSE_TAG_AF_UNIX.

В Windows биты режима, сообщаемые Lstat и Stat для точек повторной обработки, изменились. Точки монтирования больше не имеют установленного ModeSymlink, а точки повторной обработки, которые не являются символическими ссылками, сокетами Unix или файлами дедупликации, теперь всегда имеют установленный ModeIrregular. Это поведение контролируется настройкой winsymlink. Для Go 1.23 по умолчанию установлено значение winsymlink=1. Для предыдущих версий по умолчанию установлено значение winsymlink=0.

Функция CopyFS копирует io/fs.FS в локальную файловую систему.

В Windows Readlink больше не пытается нормализовать тома по буквам дисков, что не всегда было возможно. Такое поведение контролируется настройкой winreadlinkvolume. Для Go 1.23 по умолчанию установлено значение winreadlinkvolume=1. Для предыдущих версий по умолчанию установлено значение winreadlinkvolume=0.

В Linux с поддержкой pidfd (обычно Linux v5.4+) функции и методы, связанные с процессами, используют pidfd (а не PID) внутренне, что исключает потенциальное неправильное нацеливание при повторном использовании PID ОС. Поддержка Pidfd полностью прозрачна для пользователя, за исключением дополнительных дескрипторов файлов процессов, которые могут быть у процесса.

path/filepath

Новая функция Localize безопасно преобразует путь, разделенный косой чертой, в путь операционной системы.

В Windows EvalSymlinks больше не оценивает точки монтирования, что было источником многих несоответствий и ошибок. Это поведение контролируется настройкой winsymlink. Для Go 1.23 по умолчанию установлено winsymlink=1. В предыдущих версиях по умолчанию установлено winsymlink=0.

В Windows EvalSymlinks больше не пытается нормализовать тома по буквам дисков, что не всегда было возможно. Это поведение контролируется настройкой winreadlinkvolume. Для Go 1.23 по умолчанию установлено winreadlinkvolume=1. В предыдущих версиях по умолчанию установлено winreadlinkvolume=0.

reflect

В Type добавлены новые методы, синонимичные методам с тем же именем в Value:

  • Type.OverflowComplex
  • Type.OverflowFloat
  • Type.OverflowInt
  • Type.OverflowUint

Новая функция SliceAt аналогична NewAt, но для срезов.

Методы Value.Pointer и Value.UnsafePointer теперь поддерживают значения типа String.

Новые методы Value.Seq и Value.Seq2 возвращают последовательности, которые перебирают значение, как если бы оно использовалось в цикле for/range. Новые методы Type.CanSeq и Type.CanSeq2 сообщают, будет ли вызов Value.Seq и Value.Seq2, соответственно, успешным без паники.

runtime/debug

Функция SetCrashOutput позволяет пользователю указать альтернативный файл, в который среда выполнения должна записать свой отчет о фатальном сбое. Его можно использовать для создания автоматизированного механизма отчетности для всех неожиданных сбоев, а не только для тех, которые находятся в goroutines, которые явно используют recovery.

runtime/pprof

Максимальная глубина стека для профилей alloc, mutex, block, threadcreate и goroutine была увеличена с 32 до 128 кадров.

runtime/trace

Среда выполнения теперь явно сбрасывает данные трассировки, когда программа аварийно завершает работу из-за неперехваченной паники. Это означает, что более полные данные трассировки будут доступны в трассировке, если программа аварийно завершает работу во время активной трассировки.

slices

Функция Repeat возвращает новый срез, который повторяет предоставленный срез указанное количество раз.

sync

Метод Map.Clear удаляет все записи, в результате чего получается пустая карта. Он аналогичен clear.

sync/atomic

Новые операторы And и Or применяют побитовое И или ИЛИ к заданным входным данным, возвращая старое значение.

syscall

Пакет syscall теперь определяет WSAENOPROTOOPT в Windows.

Функция GetsockoptInt теперь поддерживается в Windows.

testing/fstest

TestFS теперь возвращает структурированную ошибку, которую можно развернуть (с помощью метода Unwrap() []error). Это позволяет проверять ошибки с помощью error.Is или error.As.

text/template

Теперь шаблоны поддерживают новое действие "else with", что снижает сложность шаблона в некоторых случаях использования.

time

Parse и ParseInLocation теперь возвращают ошибку, если смещение часового пояса выходит за пределы диапазона.

unicode/utf16

Функция RuneLen возвращает количество 16-битных слов в кодировке UTF-16 руны. Она возвращает -1, если руна не является допустимым значением для кодировки в UTF-16.

Порты

Darwin

Как было объявлено в примечаниях к выпуску Go 1.22, Go 1.23 требует macOS 11 Big Sur или более поздней версии; поддержка предыдущих версий прекращена.

Linux

Go 1.23 — последний релиз, требующий версию ядра Linux 2.6.32 или более позднюю. Go 1.24 потребует версию ядра Linux 3.17 или более позднюю, за исключением того, что системы под управлением 3.10 или более поздней версии будут по-прежнему поддерживаться, если ядро было исправлено для поддержки системного вызова getrandom.

OpenBSD

Go 1.23 добавляет экспериментальную поддержку OpenBSD на 64-битном RISC-V (GOOS=openbsd, GOARCH=riscv64).

ARM64

Go 1.23 вводит новую переменную среды GOARM64, которая указывает минимальную целевую версию архитектуры ARM64 во время компиляции. Допустимые значения: v8.{0-9} и v9.{0-5}. За этим может следовать параметр, указывающий расширения, реализованные целевым оборудованием. Допустимые параметры: ,lse и ,crypto.

Переменная среды GOARM64 по умолчанию — v8.0.

RISC-V

В Go 1.23 представлена новая переменная среды GORISCV64, которая выбирает профиль приложения пользовательского режима RISC-V для компиляции. Допустимые значения: rva20u64 и rva22u64.

Переменная среды GORISCV64 по умолчанию — rva20u64.

Wasm

Скрипт go_wasip1_wasm_exec в GOROOT/misc/wasm прекратил поддержку версий wasmtime < 14.0.0.


Читайте также: