Go Update
3.11K subscribers
8 photos
73 links
Канал про новости связанные с языком программирования Go. Эволюция языка, стандартной библиотеки и просто интересные вещи над которыми работает Go Core Team и не только.

Админ: @lepage_d
Download Telegram
Go Update
🎉 Вышел Go 1.24! 🎉 Этот момент настал! Ключевые нововведения: — Дженерики теперь умеют в псевдонимы (aliases) т.е. теперь можно писать так type MyType[T any] = myType[T,*T] Поздравляю тех, кому приходилось работать с указателями в дженериках, теперь…
🎉 Вышел Go 1.25! 🎉

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

♻️ Бинарей в комплекте теперь меньше. Разработчики компилятора активно использовать команду go tool у себя внутри, что убирает необходимость поставлять заготовки в комплекте. Но как минимум go build и go test бинари все еще на месте.

— Новая директива ignore в go.mod. Подробное описание тут. Если в вкратце: для этого вы раньше использовали каталог testdata и каталоги которые начинаются с точки.

— Когда go команда обновляет go 1.xx.y директиву в go.mod она больше не добавляет toolchain директиву.

go vet теперь ругается на неправильное использование sync.WaitGroup.Add и fmt.Sprintf("%s:%d", host, port) ибо есть net.JoinHostPort.

🍵 Новый экспериментальный сборщик мусора. О нем статья будет позже.

🔀️️️️️️ Новый тип runtime/trace.FlightRecorder позволяет записывать только значимые события, а не всё подряд для tracing’га (под капотом используется циклический буфер, который помнит N последних секунд).

🛠 Компилятор теперь генерирует дебаг-инфу в формате DWARF5. Практический итог: бинари едят меньше места и быстрее комбинируются.

🏎️️️️️️ Новый экспериментальный пакет encoding/json/v2. По хорошему про него тоже надо писать отдельную статью, но если в кратце — он намного быстрее того что было внутри encoding/json. А другая хорошая новость заключается в том, что если вы включили GOEXPERIMENT=jsonv2 то больше ничего менять не надо, так как encoding/json сам подключит новую внутряку.

— Тип os.Root приобрел несколько новых методов.

🏎️️️️️️ Функция reflect.TypeAssert позволяет приводить типы из reflect.Value в конкретный тип, минуя потенциально аллоцирующий вызов reflect.Value.Interface.

— Директива GODEBUG=checkfinalizers=1 позволяет понять, как дела в вашей очереди cleanup’ов и finalizer’ов во время каждого GC.

SetDefaultGOMAXPROCS позволяет сбросить настройки GOMAXPROCS если вдруг переменная прилетела через Env или через прошлый вызов GOMAXPROCS.

— Новый метод sync.WaitGroup.Go - больше нет необходимости тащить errgroup если вам не нужен был возврат ошибок и отмена контекста.

🔥testing.T/B/F теперь имеют метод Output() io.Writer который позволяет правильно редиректить вывод внутри вызова теста.

Читать про релиз вот тут.
🔥2633👍2
А ещё планируем с Колей записать подкаст по поводу релиза 1.25 где у вас будет возможность задать все интересующие вас вопросы. Вероятно объяснение нового сборщика мусора будет в первую очередь там (с помощью пальцев и активной жестикуляции).

Так что следите за анонсами 😁.

Статья здесь все равно будет, если вы не переносите видео.
17🔥10😐1
13го августа в 22:40 по Москве в канале ничего не происходить 😁.
😁307👍2
🥂Что нового в Go v1.25 — подробно обсуждаем новую версию языка

https://youtube.com/live/VHjXHzs742c?feature=share

Когда: в ближайшую субботу, 23 августа, 11:00 по Мск

Обсуждаем тем же составом, которым обсуждали когда-то Go v1.21:
- Николай Тузов
- Глеб Яльчик
- Дмтрий Матрёничев

А пока ждёте, советую почитать посты Димы на эту тему, у него очень подробные и крутые разборы

#gogetpodcast #go_1_25
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Я только сейчас понял, что у нас снова, за долгое время, совпали цифры релиза и года. Причем впервые совпали обе цифры. В последний раз это был Go 1.6 и совпала только последняя.

Таймлайн:

go1.0 2012-03-28
go1.1 2013-05-13
go1.2 2013-12-01
go1.3 2014-06-18
!go1.4 2014-12-10
!go1.5 2015-08-19
!go1.6 2016-02-17
go1.7 2016-08-15
go1.8 2017-02-16
go1.9 2017-08-24
go1.10 2018-02-16
go1.11 2018-08-24
go1.12 2019-02-25
go1.13 2019-09-03
go1.14 2020-02-25
go1.15 2020-08-11
go1.16 2021-02-16
go1.17 2021-08-16
go1.18 2022-03-15
go1.19 2022-08-02
go1.20 2023-02-01
go1.21 2023-08-08
go1.22 2024-02-06
go1.23 2024-08-13
go1.24 2025-02-11
!go1.25 2025-08-12
🔥21👍6🤯5💩2
👁Визуализатор нашего трехцветного сборщика мусора.

Сегодня на подкасте я упомянул, что у нас трехцветный сборщик мусора. Для меня, как человека, который привык разбирать вещи «на практике или в действии» самым лучшим объяснением выступил визуализатор от ребят из Pusher который они сделали в рамках своей своей статьи про его особенности. И хотя статье уже почти 8 лет, ничего из основ, которые в нее положены, с тех пор не поменялось. В общем: очень и очень рекомендую.

Так-же есть хорошая статья про сборщик мусора от Авито (хотя секция про Write Barrier довольно тяжела для восприятия) и цикл статей от Ardan Labs о основах памяти и о том как правильно читать выводы рантайма про сборку мусора.
🔥29
🚀 Расширение функции new для создания указателя на значения 🚀

Отличные новости! Предложение, обсуждение которого которого длится уже больше четырех лет и которое выдвинул сам Роб Пайк, наконец-то подходит к принятию приняли!

В чем суть: есть у нас встроенная функция new, которая принимает тип и возвращает указатель на значение этого типа. Хорошая функция, однако исторически так сложилось, что она была в тени оператора "&" который использовался и для создания указателей на комплексные типы и для взятия адреса существующих переменных. С учетом того, что для создания словарей, каналов и срезов используется функция make, прикладного постоянного использования у new было немного.

Однако у оператора "&" тоже есть недостатки. Самый явный — он не умеет работать со значениями примитивов (т.е. нельзя сделать a := &1, такой код просто не скомпилируется). Другая проблема в том, что для продолжения работы с указателем, в месте его взятия, нам нужно помещать выражение в скобочки. Т.е. нельзя написать &myComplexType{}.CallStuff() но можно написать (&myComplexType{}).CallStuff().

И вот теперь, спустя 13 лет после релиза языка, нас ждет камбэк функции new так как ее новый синтаксис будет принимать как типы, так и значения. Текущее предложение делает корректным вот такий синтаксис:


a := new(123)
b := new(myConstant)
c := new(int64(-123))



А сие значит, что вероятно точно уже в 1.26 можно будет избавится от хелперов, таких как:

func ptrTo[V any](v V) *V { return &v }


Маленькое, но давно назревшее изменение, принятию которого (пускай и в слегка измененной версии) рад даже сам Пайк.
46🔥28👍18
Тут появилась запись нашего подкаста где мы обсуждали 1.25. Получилось довольно неплохо, как и говорил — поводил руками при объяснении нового сборщика мусора. Ну и про другие вещи не забыли.
2👍2🔥1
🥂Выпуск про Go 1.25 уже доступен / GoGetPodcast 17

https://youtu.be/fHuJNsZPCJ0

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

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

🟢Наш подкаст обычно собирает значительно меньше просмотров, чем прочие мои ролики. При этом я знаю, что есть люди, которые очень его любят. Поэтому, если он вам интересен, вы можете помочь алгоритмам Ютуба в его продвижении:

- Досмотривайте выпуски до конца
- Подписывайтесь на канал
- Ставьте лайки
- Делитесь с друзьями и коллегами

Это правда очень важно.

🫶 Чем быстрее растёт аудитория подкаста, тем чаще будут выходить новые выпуски, и тем больше я буду вкладываться в их качество.

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

#gogetpodcast #news
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥7👍2
🏗️ gogrep — инструмент для семантического поиска внутри вашей кодовой базы. 🏗️

Наверняка много кому приходилось сталкиваться с ситуацией «надо по коду найти вызовы по определенному паттерну». Чаще всего для этого мы используем регулярные выражения (grep, ag, rg). Однако у них всех есть один минус — они интерпретируют файлы как текст, а не как код. Из-за этого в результаты поиска попадают как нужные нам места вызова, так и комментарии, участки текста и прочая.

Решение этой проблемы: семантический поиск. Это когда утилита разбивает файл на синтаксическое дерево и производит поиск уже по самому дереву. Приведу простой пример:

~/mws/api > gogrep . 'ptr.Get($_)'


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

Документация по gogrep доступна тут. С описанием синтаксиса немного сложнее: большую (и лучшую) часть информации по мэтчингу и по фильтрам можно найти в тестах. Сама тулза является часть куда более мощной тулзы go-ruleguard (которая кстати входит в golangci-lint).

За обе утилиты огромнейшее спасибо Искандеру Шарипову.
14👍6
Go Update
🏗️ gogrep — инструмент для семантического поиска внутри вашей кодовой базы. 🏗️ Наверняка много кому приходилось сталкиваться с ситуацией «надо по коду найти вызовы по определенному паттерну». Чаще всего для этого мы используем регулярные выражения (grep,…
Тут мне справедливо заметили, что есть и другие утилиты подобного толка, которые и умеют больше и языков поддержка у них шире. Соглашусь. Для исторической правды приведу те, которые известны лично мне:

semgrep — один из старейших инструментов статического анализа. Поддерживает больше 30 языков, имеет GUI, поддерживает файл с комплексными правилами и вообще комбайн. Недостаток только один: для использования некоторого функционала нужна коммерческая лицензия. Рекомендую глянуть набор правил (часть написана на ruleguard о котором ниже) от Дэмиена Граски для понимания всех возможностей которые может данная утилита.
opengrep — после того как ребята ответственные с утилиту из прошлого пункта решили переехать на коммерческие рельсы, коллектив из нескольких AppSec команд форкнул проект и продолжил развивать его самостоятельно. Умеет почти все (и даже больше), что умеет semgrep, и весь функционал абсолютно бесплатный.
ast-grep — относительный новичок в поле поиска по паттерну в AST. Написан на Rust. Поддерживает трансформацию кода и меньше, чем прошлые две утилиты, ориентирован на поиск проблем с безопастностью.

При всех плюсах вышестоящих утилит, для меня главный их минус в их универсальности. Для каждой из них Go не является основным языком, что ограничивает мощности паттернов по поиску и трансформации. Более того, ruleguard (который частично/полностью основан на gogrep) поддерживает возможность написания трансформаторов кода (автоматический рефакторинг) на Go, а значит не нужно учить и запоминать еще один синтаксис. Плюс из коробки у нас интеграция с go/build, go/ast, go/tokens и go/types что позволяет получить всю мощь Go инструментария не выходя за пределы утилиты.
👍9🔥31👏1
Go Update
Опросы в канале, да или нет? Там ко мне пришли с рекламой с предложением разместить опрос. Я обычно никакие опросы никогда сам не прохожу (кроме Go Developer Survey), поэтому оставляю решение за аудиторией. Как проголосуете, так и будем делать. П.С. Рекламы…
Есть такая старинная мудрость, о которой я регулярно забываю: «Никогда не говори Никогда». Ибо приходиться потом стыковать неидеальную жизнь с идеалистичными заявлениями. Тем более я никогда не думал, что мой бред мои очерки будет читать почти три тысячи человек.

За более чем два года, с момента цитируемого сообщения, ко мне приходило достаточно большое число людей (и гораздо больше чем я вообще ожидал) с разными предложениями: от продажи канала, до интеграций с разными площадками. Большинство (включая продажу) я отклоняю сразу без вопросов — если бы я делал блог на продажу, я бы не делал его таким личным. Большинство рекламных сообщений я так-же отклоняю, потому как считаю неразумным размещать вещи в которых я не уверен, ради относительно небольшого дохода. Сюда же идёт любой инструментарий для автоматического размещения рекламы. Да и текущая активность канала приведет к тому, что доля рекламы быстро приблизиться к негуманным «один-к-одному» и читать станет невозможно. Любые интеграции я оставляю на подумать, но мне никогда не хватает времени, что-бы к ним потом вернуться 😁️️️️️️.

Что подводит нас к маленькому, но важному: есть небольшой процент вещей, за которые я готов вписаться или которые мне интересны, и которые я готов тут размещать. При обязательном условии, что они попадают под тематику канала. Более того, технически я уже нарушал своё же правило: когда размещал объявления о своих выступления на других конференциях и/или подкастах.

Поэтому, в целях прозрачности, с сегодняшнего дня я думаю немного изменить вышестоящее правило:

1. Я буду рассказывать про те вещи (конференции, подкасты, митапы, курсы и прочее) за которые я готов «вписаться». Сюда входят мероприятия, в которых либо я сам принимаю участие (хоть и не организовываю), либо организаторы являются людьми в которых я уверен.
2. Я так-же возможно буду рассказывать про вещи которые мне интересны и могут быть интересны читателям. Сюда идут конференции и инструменты про которые я либо знаю-слышал, либо знаю «через кого-то» и они обладают достаточной степенью доверия, но вписаться за кого я дать не готов.

«А зачем что-то менять?» последует логичный вопрос. На мой взгляд существует ряд вещей которые находятся на стыке с тематикой этого канала и которые могут быть потенциально интересны тем кто меня читает.

Притом ко всем записям по прежнему останутся открытые комментарии: если пойдет какой-то откровенный шлак, то об этом всегда можно будет написать своё «фи». Но я очень надеюсь, что до этого не дойдёт, ибо меня сильно радует, что более чем у 20 процентов моих подписчиков включены уведомления о новом потоке бреда сообщении в канале.
👍35😐1
✔️ errors.AsType — типобезопастная замена errors.As ✔️

Тем временем, в 1.26 нас (вероятно) ждет еще одно приятное изменение: дженерики наконец доберутся до пакета errors.

Все изменение проще описать тремя строчками кода. В 1.25 у нас вот так:


var pe *fs.PathError
if errors.As(err, &pe) {
fmt.Println("Failed at path:", pe.Path)
}


А в 1.26 можно будет вот так:


if pe, ok := errors.AsType[*fs.PathError](err); ok {
fmt.Println("Failed at path:", pe.Path)
}


Вроде и небольшое изменение, но оно ведет, как минимум, к двум положительным вещам:
• Зона видимости типизированной ошибки во многих участках у нас теперь будет меньше, а значит меньше захламляется пространство имен и снижается необходимость думать над правильным именем для ошибки.
• В отличии от errors.As, который вторым аргументом принимал any, новая функция принимает только тех, кто реализует интерфейс error. Несмотря на то, что у нас есть проверка внутри go vet проверяющая второй аргумент у As, всегда приятнее когда компилятор может самостоятельно поймать ошибку на этапе сборки приложения.

Кстати, причина по которой сигнатура текущей функции выглядит как As(err error, target any) bool заключается в том, что указатель на интерфейс и указатель на тип реализующий интерфейс для компилятора две несовместимые конструкции. Иначе говоря, вот такой код


func As(err error, target *error) bool {
panic("unimplemented")
}



pe *fs.PathError
if As(err, &pathError) {
fmt.Println("Failed at path:", pathError.Path)
}





компиляцию не пройдет. А причина в том, что интерфейсы у нас это отдельная сущность которая существует не только во время компиляции, но и во время выполнения.
👍24🤮7🔥41
Я тут выступать подписался на 14ую Стачку в Питере. 2го октября на сей конференции, я буду рассказывать про интересное:

Итераторы: не опять, а снова.

Расскажу про дизайн и эволюцию итераторов. Начну с того, как про них писали в "Паттернах проектирования" и какими были итераторы в Go 1.0. Как разработчики пришли к текущему дизайну "range-over-func", какие проблемы пришлось решить (почему переделали циклы for). Почему большинство Go разработчиков уже пишет итераторы, но еще не знает об этом. Расскажу про то, как это работает под капотом и насколько все хорошо/плохо с производительностью, почему итераторы это не только про скорость. И в заключении расскажу о том, как мы используем итераторы в MWS Cloud Platform и где их использовать не стоит.


А еще мне как спикеру выдали промокод GOPHER10 - дающий скидку 10% на покупку билета. В общем если раздумывали о том, пойти или нет, то у вас есть еще один аргумент за.

П.С. Сентябрь дрянь. Квартира — инфекционный бокс уже третью неделю. Надеюсь, что дальше будет лучше.
🔥222
Go Update
❄️ runtime/secret: add new package: о тех кто застрял в лимбе. Как часто вы зануляете память? Подозреваю, что ответ большинства Go разработчиков будет где-то между "никогда" и "зачем?". И действительно, в большинстве приложений такая задача никогда не появляется.…
🔐runtime/secret: secret.Do 🔐

Тем временем, абсолютно буднично и рутинно произошло хорошее: пакет runtime/secret получил свою реализацию и будет доступен в Go 1.26 (правда будет скрыт за флагом GOEXPERIMENT=runtimesecret устанавливаемым во время компиляции).

Собственно весь пакет состоит из одной функции: secret.Do, которая принимает на вход функцию с сигнатурой func() и подчищает за ней следующие вещи на выходе из этой функции:
Весь стек который использовался во время работы горутины заполняется нулями. Если при работе стек «рос» (по факту — копировался в новое место) то прямо во время копии старый участок памяти рантайм заполнит нулями.
Все регистры ЦПУ которые «могут содержать секреты» будут заполнены нулями после выхода. Подозреваю, что здесь речь идет о регистрах которые не используются самим рантаймом для служебных действий (верх, низ стека и прочая).
Если в процессе работы переданной функции мы создаем объекты в хипе, то сразу после сборки мусора, их память будет заполнена нулями.
Если внутри передаваемой функции произошла паника, подменяют стектрейс, что-бы скрыть любую информацию о переданной функции.

Для большинства это изменение ничего не меняет.

Но для тех кто работает с криптографией (включая TLS которое мы все используем в HTTPS, HTTP/2 и gRPC без флага insecure) это хорошая новость, которая позволяет усилить защиту приложений и усложнить чтение секретов злонамеренными акторами, даже если скомпрометирована вся железка. Плюс «надежную» очистку секретов часто требуют при сертификации софта в разных регионах нашей планеты.

П.С. Пакет пока доступен только для архитектур amd64 и arm64 (если вы не поняли, что это значит, это хорошо тк вы точно попадаете в доступные архитектуры).
П.П.С. Так-же пока пакет работает только под Linux.
🔥435🤯1
Про go mod tidy | verify | download

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

Я думаю, что нет, ибо работает простой принцип: работает — не трогай. Однако мне, по роду деятельности, пришлось залезть внутрь и прочитать (несколько раз) спеку и посмотреть реализацию. И для того, чтоб структурировать свои изыскания я пишу сей пост.

Все начинается с попытки получить модуль. После первого скачивания модуля (через вызов go mod tidy или go mod download на проекте) в формате zip архива с прокси для модулей, Go делает следующее

Сортирует имена файлов в архиве и пробегает sha256 по каждому файлу. Получившийся набор пар "hash filepath" он прогоняет через sha256 еще раз, кодирует его в base64, добавляет префикс h1: и запоминает результат. В общем виде это выглядит как вызов вот такой команды:


sha256sum $(find . -type f | sort) | sha256sum


Далее он сравнивает получившийся хеш с записью о зависимости которая хранится в go.sum внутри вашего проекта. Если её нет (или нет go.sum, т.е. вы только начали проект) то он идет в GOSUMDB и спрашивает хеш у него. В обоих случаях, после совпадения хешей, zip файл модуля пишется в локальные загрузки ($GOPATH/pkg/mod/cache/download/<url>) и распаковывается в локальный кеш ($GOPATH/pkg/mod/cache/<url>). Если не совпало, ничего не пишем и кидаем ошибку. Побочный вывод — нельзя называть модуль cache или sumdb, о чем ниже.

- Если модуль приватный (выставлены переменные окружения GOPRIVATE и/или GONOSUMDB) или вообще отключена связь с сервером хешсумм через GOSUMDB=off, то проверять хешсумму он будет исключительно с тем, что есть в go.sum внутри проекта. Если там такого модуля нет, то мы доверяем полученным данным и добавляем полученную хешсумму в go.sum.

- Если нет прокси для модулей (например вы берёте файлы напрямую с гита) то Go сам создает zip архив и помещает его в скаченное.

- Подсчет хеша архива модуля недешевая операция в общем смысле, особенно если её постоянно вызывать. Поэтому, кроме zip файла модуля мы рядом храним полученный хеш в файле c суффиксом .ziphash.

Во время сборки бинаря наш компилятор, чтобы не терять время, не проверяет целостность архива и распакованных данных, а только сравнивает, что строчки в go.sum проекта совпадают с тем, что у нас лежит в ziphash файлах.

И тут наступает вопрос: а как проверить, что никто не трогал наш кеш модулей? В дело вступает go mod verify, который пробегаясь по всем модулям из go.mod делает следующее:

Сначала он читает хеш из ziphash файла.
Затем он читает и хеширует распакованные файлы модуля, сравнивая их итоговый хеш с полученным на прошлом этапе. Затем тоже самое повторяется для zip архива модуля. Операция аналогична тому, что происходит при скачивании.
Если не совпало, то verify кидает ошибку на модуль и выходит.

Обратите внимание, что здесь go.sum проекта нигде не участвует. Проверяется целостность именно кеша.

А что если мне подменили ziphash вместе с файлами модуля и zip архивом? На это есть ряд ответов:

Во время скачивания предполагается, что между нами и БД хешсумм установленно защищенное соединение.
Сама БД хешей, это даже не БД в общем смысле, а дерево, где каждый новый элемент зависит от прошлых вставок. Поэтому при попытке поменять запись развалятся записи о всех хешах модулей которые были вставлены после. Кому интересны подробности рекомендую вот эту статью https://research.swtch.com/tlog и погуглить Merkle Tree.
Когда мы скачиваем хеш, мы получаем не отдельное значение, а некое «поддерево» хешей которое необходимо нам для валидации нашего модуля. Это дерево мы помещаем в $GOPATH/pkg/mod/cache/download/sumdb/ (тот самый) и используем для проверки локального модуля. И тут происходит интересное: если удалить ziphash файл то даже без соединения с интернетом, go mod download сможет восстановить хеши из частей большого дерева лежащих в $GOPATH/pkg/mod/cache/download/sumdb/ и записать их обратно в ziphash.
👍164🤯3🔥1
Про go mod tidy | verify | download (Part 2)

Получается, что на практике подделать запись (или случайно закараптить модуль) довольно сложно, тк проверка идет из нескольких мест. Однако потенциальная атака существует:

Атакующий может переписать модуль, его архив и ziphash файлы.
Затем атакующий переписывает хеш внутри go.sum ваших проектов.
Тогда, даже если вы перед сборкой делаете go mod download и go mod verify, то компилятор не заподозрит подмену.

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


find $GOPATH/pkg/mod/cache/ -type f -name "*.ziphash" | xargs -rn1 rm
🔥43👍1🗿1
Forwarded from Thank Go! (Anton Zhiyanov)
Интерактивный тур по Go 1.26

Опубликовал традиционный тур по будущему релизу (на англ). Часть фич мы с вами уже разобрали, а часть еще разберем, но если хотите прочитать все вместе уже сейчас — добро пожаловать.

Вот что вошло:

— new(expr)
— Безопасная проверка ошибок
— Новый «чайный» GC
— Ускоренный cgo и выделение памяти
— SIMD для amd64
— Секретный режим
— Криптография без ридеров
— Профиль для ловли утекающих горутин
— Метрики состояния горутин
— Итераторы в reflect
— Подсматривание в байтовый буфер
— Дескриптор процесса ОС
— Сигнал как причина в контексте
— Сравнение IP-подсетей
— Dialer с контекстом
— Фальшивый example.com
— Оптимизированные fmt.Errorf и io.ReadAll
— Множественные хендлеры в логах
— Артефакты тестов
— Обновленный go fix

Это жесть сколько всего они в релиз запихнули 😅

https://antonz.org/go-1-26
🔥1732
Антон традиционно публикует список нововведений которые приедут к нам с Go 1.26. Самое интересное это new(…expr…), pprof для ловли утечки горутин и обновленный go fix. Рекомендую ознакомится, тем более всё представлено в интерактивном виде.
🔥3
🚀️️️️️️ proposal: spec: direct reference to embedded fields in struct literals 🚀️️️️️️

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


type E struct {
A int
}

type T struct {
E
}

var v T
v.E.A = 100
println(v.A)


Однако «символьная» инициализация подобной структуры всегда требовала полный синтаксис:


v := T{E: E{A: 1}}


Читается сие, на мой взгляд, довольно сложно. Есть и другая проблема: такую методику «выноса» нельзя использовать как рефакторинг, ведь мы ломаем инициализацию у пользователей нашего кода. Этим озаботились и сами разработчики компилятора Go, и предложили разрешить обращаться к полям встроенной структуры, как к родным в момент инициализации. Т.е. В будущем можно будет писать и так:


v := T{A: 1}


Правда есть одно но: а что делать если встроена не структура, а указатель? Кидать панику? Делать «неявную» аллокацию для встроенного указателя? А если таких «встроек» несколько?

Из-за потенциальной (и множественной) сложности выводов, на данный момент, принято решение разрешить новый синтаксис инициализации только для полей-значений. Т.е. код


type F struct {
*E
}

v := F{A: 100}


как и раньше, не скомпилируется. На мой взгляд, это хорошее решение.

Статус issue: likely accept, а значит есть все шансы увидеть новый синтаксис в Go 1.27.

П.С. Само предложение датируется аж 2015ым. Похоже Go Team основательно взяла курс на разгребание старых проблем.
👍13