Примечания к выпуску Go 1.25
Введение в Go 1.25
Последний выпуск Go, версия 1.25, выходит в августе 2025, через шесть месяцев после Go 1.24. Большинство изменений касаются реализации инструментария, среды выполнения и библиотек. Как и всегда, выпуск сохраняет обещание совместимости Go 1. Ожидается, что почти все программы на Go продолжат компилироваться и выполняться так же, как и раньше.
Изменения в языке
В языке нет изменений, влияющих на программы на Go в версии 1.25. Однако, в спецификации языка понятие «core types» было удалено в пользу более подробного текста. См. соответствующую запись в блоге для получения дополнительной информации.
Инструменты
Команда go
Опция go build -asan теперь по умолчанию выполняет проверку утечек памяти при завершении программы.
Это приведет к выводу ошибки, если память, выделенная C, не освобождена и не ссылается ни на какую другую память, выделенную либо C, либо Go.
Эти новые сообщения об ошибках могут быть отключены установкой
ASAN_OPTIONS=detect_leaks=0 в окружении при запуске программы.
Дистрибутив Go будет содержать меньше предварительно скомпилированных исполняемых файлов инструментов. Основные двоичные файлы инструментария, такие как компилятор и линкер, по-прежнему будут включены, но инструменты, которые не вызываются операциями сборки или тестирования, будут собираться и запускаться по мере необходимости через go tool.
Новая директива ignore в go.mod может быть использована для указания каталогов, которые команда go должна игнорировать. Файлы в этих каталогах и их подкаталогах будут проигнорированы командой go при сопоставлении паттернов пакетов, таких как all или ./..., но по-прежнему будут включены в zip-файлы модулей.
Новая опция go doc -http запустит сервер документации, показывающий документацию для запрашиваемого объекта, и откроет документацию в окне браузера.
Новая опция go version -m -json выводит JSON-кодирование структур runtime/debug.BuildInfo, встроенных в указанные двоичные файлы Go.
Команда go теперь поддерживает использование подкаталога репозитория в качестве пути корня модуля при разрешении пути модуля с использованием синтаксиса
<meta name="go-import" content="root-path vcs repo-url subdir">, чтобы указать, что root-path соответствует subdir репозитория repo-url с системой управления версиями vcs.
Новый шаблон пакетов work соответствует всем пакетам в рабочем (ранее называвшемся main) модуле: либо единичному рабочему модулю в режиме модуля, либо набору модулей рабочей среды в режиме рабочей среды.
Когда команда go обновляет строку go в файле go.mod или go.work, она больше не добавляет строку toolchain,
указывающую текущую версию команды.
Vet
Команда go vet включает новые анализаторы:
- waitgroup,
который сообщает о неправильном вызове
sync.WaitGroup.Add; и
- hostport,
который сообщает об использовании
fmt.Sprintf("%s:%d", host, port)для построения адресов дляnet.Dial, так как это не будет работать с IPv6; вместо этого он предлагает использоватьnet.JoinHostPort.
Среда выполнения
Контейнеросознательный GOMAXPROCS
Поведение GOMAXPROCS по умолчанию изменилось. В предыдущих версиях Go,
GOMAXPROCS по умолчанию равен количеству логических процессоров, доступных при запуске
(runtime.NumCPU). Go 1.25 вводит два изменения:
-
В Linux среда выполнения учитывает ограничение пропускной способности CPU группы контроля (cgroup), содержащей процесс, если таковая имеется. Если ограничение пропускной способности CPU ниже, чем количество доступных логических процессоров,
GOMAXPROCSбудет по умолчанию установлено на меньшее ограничение. В системах контейнеризации, таких как Kubernetes, ограничения пропускной способности CPU cgroup обычно соответствуют параметру «CPU limit». Среда выполнения Go не учитывает параметр «CPU requests». -
На всех операционных системах среда выполнения периодически обновляет
GOMAXPROCS, если количество логических процессоров или ограничение пропускной способности CPU cgroup изменяется.
Оба этих поведения автоматически отключаются, если GOMAXPROCS установлен вручную через переменную окружения
GOMAXPROCS или вызов runtime.GOMAXPROCS. Их также можно отключить явно с помощью настроек GODEBUG
containermaxprocs=0 и updatemaxprocs=0 соответственно.
Чтобы поддерживать чтение обновлённых ограничений cgroup, среда выполнения будет кэшировать дескрипторы файлов для файлов cgroup на протяжении всего времени жизни процесса.
Новый экспериментальный сборщик мусора
Новый сборщик мусора теперь доступен в экспериментальном режиме. Дизайн этого сборщика улучшает производительность маркировки и сканирования маленьких объектов благодаря лучшей локальности и масштабируемости CPU. Результаты бенчмарков различаются, но мы ожидаем снижение накладных расходов на сборку мусора на 10–40% в реальных программах, которые активно используют сборщик мусора.
Новый сборщик мусора может быть включён установкой GOEXPERIMENT=greenteagc во время сборки. Мы ожидаем, что дизайн продолжит развиваться и улучшаться.
Поэтому мы приглашаем разработчиков Go опробовать его и сообщить о своём опыте. См. issue на GitHub для получения дополнительных сведений о дизайне
и инструкций по предоставлению обратной связи.
Трассировка в стиле flight recorder
Трассировки выполнения среды выполнения давно предоставляли мощный, но затратный способ понимания и отладки низкоуровневого поведения приложения. К сожалению, из-за их размера и стоимости постоянной записи трассировки, они были в целом непрактичны для отладки редких событий.
Новый API runtime/trace.FlightRecorder предоставляет лёгкий способ захватить трассировку выполнения среды выполнения,
непрерывно записывая трассировку в кольцевой буфер в памяти. Когда происходит значимое событие, программа может вызвать
FlightRecorder.WriteTo, чтобы сделать снимок последних нескольких секунд трассировки в файл.
Этот подход создаёт гораздо меньшую трассировку, позволяя приложениям захватывать только те трассировки, которые важны.
Длительность и объём данных, записываемых FlightRecorder, могут быть настроены с помощью
FlightRecorderConfig.
Изменение вывода необработанного панического состояния
Сообщение, выводимое при завершении программы из-за необработанного панического состояния, которое было восстановлено и повторно вызвано, больше не повторяет текст значения паники.
Ранее, если программа вызвала панику с panic("PANIC"),
восстановила панику и затем снова вызвала панику с исходным значением, то выводилось:
<code>panic: PANIC [recovered] panic: PANIC </code>
Эта программа теперь выведет:
<code>panic: PANIC [recovered, repanicked] </code>
Имена VMA в Linux
В системах Linux с поддержкой ядром анонимных областей виртуальной памяти (VMA)
(CONFIG_ANON_VMA_NAME), среда выполнения Go будет аннотировать анонимные области
памяти, указывая их назначение. Например, [anon: Go: heap] для кучной памяти.
Это поведение может быть отключено с помощью настройки GODEBUG
decoratemappings=0.
Компилятор
nil pointer bug
В этом релизе исправлена ошибка компилятора, появившаяся в Go 1.21, которая могла некорректно откладывать проверку указателя на nil. Программы, подобные следующей, которые раньше успешно выполнялись (неправильно), теперь (правильно) будут паниковать с ошибкой nil-pointer:
<code>package main
import "os"
func main() {
f, err := os.Open("nonExistentFile")
name := f.Name()
if err != nil {
return
}
println(name)
}
</code>
Эта программа некорректна, потому что использует результат os.Open до проверки ошибки.
Если err не равен nil, то результат f может быть nil, в этом случае вызов
f.Name() должен привести к панике. Однако в версиях Go 1.21–1.24 компилятор
некорректно откладывал проверку nil до после проверки ошибки, что приводило к
успешному выполнению программы, нарушая спецификацию Go. В Go 1.25 такое больше не будет
работать. Если изменение влияет на ваш код, то решение — поместить проверку ошибки
раньше в коде, желательно сразу после инструкции, создающей ошибку.
Поддержка DWARF5
Компилятор и линкер в Go 1.25 теперь генерируют отладочную информацию с использованием
DWARF версии 5.
Более новая версия DWARF уменьшает объем пространства, необходимого для отладочной
информации в двоичных файлах Go, а также уменьшает время линковки, особенно для больших
Go-приложений.
Генерацию DWARF 5 можно отключить, установив переменную окружения GOEXPERIMENT=nodwarf5
во время сборки (эта резервная опция может быть удалена в будущих версиях Go).
Быстрее срезы
Компилятор теперь может выделять хранилище для срезов на стеке в большем числе ситуаций,
что повышает производительность. Это изменение может усиливать последствия некорректного
использования unsafe.Pointer, см., например, issue 73199.
Для выявления таких проблем можно использовать bisect tool,
чтобы найти проблемное выделение, используя флаг -compile=variablemake.
Все новые стековые выделения также можно отключить с помощью -gcflags=all=-d=variablemakehash=n.
Линкер
Линкер теперь принимает опцию командной строки -funcalign=N, которая указывает
выравнивание точек входа функций.
Значение по умолчанию зависит от платформы и не изменилось в этом релизе.
Стандартная библиотека
Новый пакет testing/synctest
Новый пакет testing/synctest предоставляет поддержку тестирования
конкурентного кода.
Функция Test запускает функцию теста в изолированной «пузырьковой» среде.
Внутри пузырька время виртуализовано: функции пакета time работают с фиктивными часами,
и часы передвигаются мгновенно, если все горутины в пузырьке заблокированы.
Функция Wait ожидает, пока все горутины в текущем пузыре не заблокируются.
Этот пакет впервые стал доступен в Go 1.24 под GOEXPERIMENT=synctest, с немного другим API. Эксперимент теперь перешёл в общедоступную версию. Старое API всё ещё присутствует, если установлен GOEXPERIMENT=synctest, но будет удалено в Go 1.26.
Новый экспериментальный пакет encoding/json/v2
Go 1.25 включает новую экспериментальную реализацию JSON, которую можно включить, установив переменную окружения GOEXPERIMENT=jsonv2 во время сборки.
При включении двух новых пакетов становятся доступны:
- Пакет
encoding/json/v2— это крупное обновление пакетаencoding/json. - Пакет
encoding/json/jsontextпредоставляет низкоуровневую обработку синтаксиса JSON.
Кроме того, при включённом эксперименте “jsonv2”:
- Пакет
encoding/jsonиспользует новую реализацию JSON. Поведение при маршалинге и демаршалинге остаётся неизменным, но текст ошибок, возвращаемых функциями пакета, может измениться. - Пакет
encoding/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,
которая пытается преобразовать интерфейс Signer в
MessageSigner, используя метод
MessageSigner.SignMessage, если преобразование успешно,
и Signer.Sign, если нет. Это может быть полезно,
когда код должен поддерживать как Signer, так и
MessageSigner.
Изменение настройки fips140 GODEBUG после запуска программы теперь не производит никакого действия (no-op).
Ранее это было документировано как запрещённое действие, и при изменении могло приводить к панике.
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
может использоваться для установки EncryptedClientHelloKey
для сервера при получении от клиента расширения Encrypted Client Hello.
Алгоритмы подписи SHA-1 теперь запрещены в рукопожатиях TLS 1.2 согласно
RFC 9155.
Их можно снова включить с помощью настройки GODEBUG tlssha1=1.
При включённом режиме FIPS 140-3 в TLS 1.2 теперь требуется Extended Master Secret, а Ed25519 и X25519MLKEM768 теперь разрешены.
Серверы TLS теперь предпочитают самую высокую поддерживаемую версию протокола, даже если это не наиболее предпочтительная версия клиента.
Как клиенты, так и серверы TLS теперь строже следуют спецификациям и отвергают нестандартное поведение. Соединения с соответствующими участниками должны остаться без изменений.
crypto/x509
CreateCertificate,
CreateCertificateRequest, and
CreateRevocationList теперь могут принимать
crypto.MessageSigner интерфейс подписи, а также
crypto.Signer. Это позволяет этим функциям использовать подписывающие интерфейсы, реализующие «одноразовые» интерфейсы подписи, где хеширование выполняется как часть операции подписи, а не вызывающей стороной.
CreateCertificate теперь использует усеченное значение SHA-256 для заполнения SubjectKeyId, если оно отсутствует.
Настройка GODEBUG x509sha256skid=0 возвращает использование SHA-1.
ParseCertificate теперь отклоняет сертификаты,
содержащие расширение BasicConstraints, которое содержит отрицательное значение pathLenConstraint.
ParseCertificate теперь более последовательно обрабатывает строки, закодированные с использованием типов ASN.1 T61String и BMPString. Это может привести к тому, что ранее принимавшиеся некорректные кодировки теперь будут отклоняться.
debug/elf
Пакет debug/elf добавляет две новые константы:
PT_RISCV_ATTRIBUTESSHT_RISCV_ATTRIBUTESдля парсинга ELF-файлов RISC-V.
go/ast
Функции FilterPackage, PackageExports, и
MergePackageFiles, а также тип MergeMode и его константы,
все устарели, поскольку предназначены исключительно для использования с
давно устаревшей механикой Object и Package.
Новая функция PreorderStack, как и Inspect, обходит синтаксическое дерево и предоставляет контроль над спуском в поддеревья, но, как удобство, также предоставляет стек содержащих узлов на каждом этапе.
go/parser
Функция ParseDir устарела.
go/token
Новый метод FileSet.AddExistingFiles позволяет добавлять существующие
File в FileSet,
или создавать FileSet для произвольного набора
File, что устраняет проблемы, связанные с использованием единственного глобального
FileSet в долгоживущих приложениях.
go/types
Var теперь имеет метод Var.Kind, который классифицирует переменную как одну из следующих: пакетная, получатель, параметр, результат, локальная переменная или поле структуры.
Новая функция LookupSelection ищет поле или метод с заданным именем и типом получателя, подобно существующей функции LookupFieldOrMethod, но возвращает результат в форме Selection.
hash
Новый интерфейс XOF может быть реализован для «функций с расширяющимся выходом», которые являются хэш-функциями с произвольной или неограниченной длиной выхода, такими как SHAKE.
Хэши, реализующие новый интерфейс Cloner, могут возвращать копию своего состояния. Все стандартные реализации Hash в стандартной библиотеке теперь реализуют Cloner.
hash/maphash
Новый метод Hash.Clone реализует hash.Cloner.
io/fs
Новый интерфейс ReadLinkFS предоставляет возможность чтения символических ссылок в файловой системе.
log/slog
GroupAttrs создаёт группу Attr из среза значений Attr.
Record теперь имеет метод Source, возвращающий информацию о месте происхождения записи или nil, если такая информация недоступна.
mime/multipart
Новая вспомогательная функция FileContentDisposition формирует заголовки Content-Disposition в формате multipart.
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 браузера, не требует токенов или cookies и поддерживает обходы на основе источника и шаблона.
os
В Windows NewFile теперь поддерживает дескрипторы, открытые для асинхронного ввода-вывода (то есть,
syscall.FILE_FLAG_OVERLAPPED указан в вызове syscall.CreateFile).
Эти дескрипторы связаны с портом завершения ввода-вывода среды выполнения Go,
что обеспечивает следующие преимущества для результирующего File:
- Методы ввода-вывода (
File.Read,File.Write,File.ReadAtиFile.WriteAt) не блокируют поток операционной системы. - Методы установки сроков действия (
File.SetDeadline,File.SetReadDeadlineиFile.SetWriteDeadline) поддерживаются.
Это улучшение особенно полезно для приложений, которые обмениваются данными через именованные каналы в Windows.
Обратите внимание, что дескриптор может быть связан только с одним портом завершения ввода-вывода одновременно.
Если дескриптор, переданный в NewFile, уже связан с портом завершения ввода-вывода,
возвращённый File переходит в режим синхронного ввода-вывода.
В этом случае методы ввода-вывода блокируют поток операционной системы, а методы установки сроков действия не работают.
Файловые системы, возвращаемые DirFS и Root.FS, реализуют новый интерфейс io/fs.ReadLinkFS.
CopyFS поддерживает символические ссылки при копировании файловых систем, реализующих io/fs.ReadLinkFS.
Тип Root поддерживает следующие дополнительные методы:
Root.ChmodRoot.ChownRoot.ChtimesRoot.LchownRoot.LinkRoot.MkdirAllRoot.ReadFileRoot.ReadlinkRoot.RemoveAllRoot.RenameRoot.SymlinkRoot.WriteFile
reflect
Новая функция TypeAssert позволяет напрямую преобразовать Value в значение Go
заданного типа. Это похоже на использование утверждения типа на результате Value.Interface,
но без лишних выделений памяти.
regexp/syntax
Синтаксисы классов символов \p{name} и \P{name} теперь принимают имена
Any, ASCII, Assigned, Cn и LC, а также псевдонимы категорий Юникода, такие как \p{Letter} для \pL.
Следуя Unicode TR18, они теперь также используют
поиск имён без учёта регистра, игнорируя пробелы, подчёркивания и дефисы.
runtime
Функции очистки, запланированные с помощью AddCleanup, теперь выполняются одновременно и параллельно, что делает очистку более пригодной для интенсивного использования, например, в пакете unique. Следует отметить, что отдельные функции очистки всё ещё должны передавать свою работу в новую горутину, если они должны выполняться или блокироваться на длительное время, чтобы избежать блокировки очереди очистки.
Новая настройка GODEBUG=checkfinalizers=1 помогает находить типичные проблемы с финализаторами и функциями очистки, такие как описанные в руководстве по сборке мусора.
В этом режиме среда выполнения запускает диагностику на каждой итерации сборки мусора и также регулярно выводит длину очередей финализаторов и очистки в stderr, чтобы помочь выявить проблемы с долгоживущими финализаторами и/или функциями очистки.
См. документацию по GODEBUG для получения дополнительных сведений.
Новая функция 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") выводит:
<code>=== ATTR TestF key value </code>
С флагом -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 и содержащие Handle, ранее требовали нескольких циклов сборки мусора для очистки, пропорционально глубине цепочки значений Handle.
Теперь, как только они становятся неиспользуемыми, они собираются немедленно в один цикл.
Порты
Darwin
Как было объявлено в примечаниях к выпуску Go 1.24, Go 1.25 требует macOS 12 Monterey или более поздней версии. Поддержка предыдущих версий была прекращена.
Windows
Go 1.25 — это последний выпуск, который содержит испорченный 32-битный порт windows/arm (GOOS=windows GOARCH=arm). Он будет удален в Go 1.26.
AMD64
В режиме GOAMD64=v3 или выше компилятор теперь будет использовать инструкции fused multiply-add, чтобы сделать арифметику с плавающей точкой быстрее и точнее.
Это может изменить точные значения с плавающей точкой, которые генерирует программа.
Чтобы избежать объединения, используйте явное приведение к float64, например float64(a*b)+c.
Loong64
Для поддержки Loong64 были приняты следующие предложения: