tgindex
Golang Дайджест

Golang Дайджест

Статистика

Самое интересное из мира Go: новости, статьи, проекты, сервисы, изменения в языке и др. Посты публикуются не часто - только самое важное, с чем я лично ознакомился. Поэтому можно не мьютить канал =) Обратная связь: @justskiv

Последний пост
13 авг.
Последнее чтение
14:47
Постов за неделю
2
Всего постов
37
Тип
открытый
Язык
русский
Категория
Новости и СМИ
В каталоге с
12 авг.
Подписчики
9 015
−3 за 4 дн.
Сутки
−1
−0,01%
Неделя
 
Месяц
 
Просмотров на пост
7 069
37 постов
Вовлечённость
78,4%
к подписчикам
Постов в день
0,3
всего 37
Упоминаний
3
каналов
Охват размещения
оценка
1/24сутки в ленте
2 316
1/48двое суток
2 654
1/72трое суток
2 862

Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.

Посты

  • 13 авг.2 123309

    📆Канал с разборами внутренностей Go и не только Хочу порекомендовать вам ещё один канал, который сам давно почитываю — очень крутые глубокие разборы и авторский стиль, всё как я люблю. Не реклама, честная рекомендация 🫶

  • 11 авг.3 1002183

    SIMD в Go 1.27 https://habr.com/ru/articles/1062972/ Раз уж в Go завозят SIMD, вот хороший разбор по нему. Начинается с ликбеза — как процессор вообще складывает числа, что такое векторные регистры и полосы, почему одна инструкция может сложить восемь чисел за раз. Дальше автор берёт go1.27rc2 и проверяет всё руками на двух машинах: M3 Pro и i9-14900KF. Напомню, что в 1.27 под флагом GOEXPERIMENT=simd обещают портируемый пакет simd: типы вида Float32s, у которых ширина неизвестна на этапе компиляции. Компилятор кладёт в бинарь четыре ветки (@simd0/128/256/512) и на рантайме выбирает нужную. Основные тезисы разбора: - Дизассемблер: FADD против VADDPS - Откуда берётся ускорение — и почему обещанные 8x на практике превращаются в 5x - Стена памяти: пока массив влезает в L3 — 5x, а дальше упор в память и 2.2x - P-ядра против E-ядер и куда вообще сядет ваш бенчмарк - Где SIMD не помогает #go1_27 #article #performance #simd

  • 17 июл.6 0628495

    🦄 Go 1.27: дженерик-методы, json/v2 в проде и профиль утёкших горутин 🟠Draft release notes — релиз ожидается уже в августе Главное — дженерик-методы Я писал об этом ещё на этапе пропозала, поэтому подробно описывать тут не буду. Вкратце: метод теперь может объявлять собственные типовые параметры. Долгое время такое приходилось писать в виде обычной функции: // Было — только обычной функцией func MapSlice[T, U any](s Slice[T], f func(T) U) Slice[U] // Стало — можно методом func (s Slice[T]) Map[U any](f func(T) U) Slice[U] То есть, мы писали MapSlice(s, f) вместо s.Map(f). Потому что метод так не умел. Теперь умеет. Из ограничений: методы интерфейсов свои типовые параметры объявлять не могут, и дженерик-метод не может реализовать метод интерфейса. Другие изменения в языке: 1. Поле встроенной структуры теперь можно задать прямо в литерале: // Было u := User{Timestamps: Timestamps{CreatedAt: now}, Name: "Вася"} // Стало u := User{CreatedAt: now, Name: "Вася"} Читать и писать в u.CreatedAt напрямую можно было всегда, а теперь и в литерале. Тикету одиннадцать лет 🙃 2. Компилятор наконец-то сам везде выводит тип: func g[T any](T) {} type S struct{ f func(int) } // Было s.f = g // ok s = S{f: g} // ошибка, нужно g[int] // Стало s = S{f: g} // ok Тип поля известен, T выводится однозначно — но в литерале это почему-то не работало. Теперь работает везде: литералы структур, массивов, слайсов и мап, отправка в канал, конверсии. Griesemer в issue сам назвал это скорее багом, чем языковым изменением. Доехал encoding/json/v2 И самое интересное — v1 теперь под капотом работает на v2. Поведение сохранено, тексты ошибок могут отличаться. Marshal примерно как был, Unmarshal заметно быстрее. Мигрировать не обязательно, v1 API будут поддерживать и дальше. Если что-то сломается — GOEXPERIMENT=nojsonv2. Goroutine leak profile доехал из экспериментального в стабильный Искать тут: /debug/pprof/goroutineleak Рантайм ловит утёкшие горутины через GC — если горутина заблокирована на примитиве, до которого не дотянется ни одна runnable-горутина (и ни одна из тех, кого те могли бы разбудить), значит разблокировать её некому. Ловит не всё, но большой класс — да. Сделал Vlad Saioc из Uber. Что ещё интересного: - Новый пакет uuid в стандартной библиотеке ✨ - Response.Body при Close сам дочитывает остаток тела — чтобы соединение ушло в пул, а не закрывалось. В разумных пределах и только для HTTP/1. Наш любимый io.Copy(io.Discard, resp.Body) можно выкидывать в большинстве случаев 🔥 - Некоторые аллокации мелких объектов (<80 байт) до 30% быстрее. В реальных allocation-heavy программах ~1%, бинарь +60 КБ - strings.CutLast и bytes.CutLast — режут по последнему вхождению сепаратора - net/url: URL.Clone() и Values.Clone() - go doc умеет package@version и флаг -ex для примеров - Unicode 15 → 17 - macOS 13 Ventura и новее. Как и обещали в 1.26 ———— 🟢 Дженерик-методы — та фича, которую ждали с самого выхода дженериков в 1.18. Как по мне, главный итог даже не «стало можно», а то, что перестанет расти пакетный неймспейс из функций, которые логически принадлежат типу. А вот с json/v2 интересно. Тихо переключить v1 на новую реализацию — смелый ход, учитывая сколько кода в мире парсит этот пакет. Обещают такое же поведение, но так не бывает. Да и GOEXPERIMENT=nojsonv2 в релиз-нотах как бы намекает 🌚 Вполне можно ожидать, что в первые месяцы будем читать байки про «а у нас после апгрейда...». uuid в стандартной библиотеке — это здорово. Сколько лет google/uuid был де-факто стандартом — пора уже добавить в stdlib. Релиз ещё черновой, так что что-то может доехать или отвалиться. ———— Я сейчас готовлю большой интерактивный разбор этого релиза на своей новой платформе, которую недавно анонсировал. Если вам что-то из текущего поста было непонятно — после прочтения разбора поймёте, там я постарался изложить всё подробно и простым языком, да ещё и с живыми примерами. Скорее всего, опубликую уже на днях (и разбор, и первую статью из обновлённой серии про планировщик). #go1_27 #go_official #generics #json

  • 12 мая7 9812029из go_update

    ⚠️ CVE-2026-42501 или почему вам нужно обновиться до Go 1.26.3/go1.25.10 ⚠️ Те кто давно работают с Go (или читают меня) знают, что целостность наших модулей гарантируется не только HTTPS транспортом до самой прокси, но и отдельной базой SumDB, которая хранит в себе хеши модулей подписанные приватным ключом. При этом сама база устроена так, что невозможно внести изменения в прошлые записи, без каскада изменений в новые, тк каждый блок «подписан» предыдущим. Но в ИБ сама безопастность это устойчивость самого слабого звена в цепочке. Достаточно одной маленькой ошибки, что-бы вся надежно выстроенная архитектура ИБ превратилась в пыль. Так и случилось в нашем случае. Рассмотрим сценарий: при получении модуля от прокси, Go проверяет его хеш с использованием SumDB, блоки которой, как я уже говорил выше, подписаны приватным ключом. В псевдокоде это выглядит следующим образом: for _, line := range sumdbResponse { if line относится к нужному module@version { if hash не совпадает { return SECURITY ERROR } } } return nil На первый взгляд, всё кажется логичным: если пришел ответ, проверяем хеш нужного модуля и при несовпадении валимся с ошибкой. При совпадении выходим из функции и продолжаем работу. Однако здесь кроется одна маленькая, но критичная деталь: что будет если нам вернут ответ без записей или запись про другой модуль? Скомпроментированная прокся может отдать специально подготовленный ответ, который наш клиент воспримет как правильный — достаточно выдать ответ с корректными хешами для любых модулей или даже выдать ответ без хешей. Поскольку go get пишет записи в go.sum с локально подсчитанного хеша, подмену никто не заметит, и тулинг спокойно продолжит работу, положив модуль от скомпрометированной прокси в go.mod/go.sum. Который, в свою очередь, будет использован компилятором при сборке проекта. Т.е. перед нами классическая уязвимость которая позволяет организовать Supply Chain Attack (атака на зависимости), пример которой можно описать вот так: 1. Прокся отдаёт клиенту изменённый архив модуля, например rsc.io/foo@v1.0.0. 2. На запрос хеша возвращается валидный, криптографически корректный ответ от checksum database, но для другого модуля, например rsc.io/bar@v1.0.0. 3. go get видит: «ответ sumdb валидный, несовпадающего хэша нет» — и продолжает работу. Т.е. вы получаете измененный модуль, у которого хеш оригинала можно узнать только после удаления go.sum и изменения прокси или использования direct в GOPROXY. Проблема бы не была такой большой (ибо у большинства переменную GOSUMDB, отвечающую за источник правды о хешах, никто не трогает, а для загрузки тулчейна её вообще невозможно переопределить) если бы не два но: • Директивы toolchain и go позволяют выбирать нужную версию компилятора автоматически, и при необходимости, скачивать её с той же самой прокси. • go get всегда сначала спрашивает проксю, может ли та проксировать запросы до базы хешей GOSUMDB. Если ответ положительный, то она просто спросит её о хеше, вместо обращения непосредственно к GOSUMDB. В этой ситуации фактически всю цепочку доставки модулей до клиента (и тулчейнов, если явно не запрещен автовыбор) контролирует один узел. Поэтому, если у вас изменена GOPROXY или вы не доверяете сертификатам TLS установленным в системе, то я очень рекомендую вам обновиться. При этом вам недостаточно обновить версию go (или toolchain) в файле go.mod, ведь изначальный тулчейн будет по-прежнему работать по старой логике. Нужно именно установить новую версию компилятора, заменив ту которая стоит «по умолчанию» в системе, а затем прогнать rm go.sum && go mod tidy в проектах которые могут быть скомпрометированы. При всей опасности атаки, фикс у неё самый тривиальный: return nil просто заменили на return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum missing from sumdb response"+sumdbAbsent, noun)) П.С. Именно поэтому я рекомендую использовать приложения типа direnv для установки переменных GOPROXY или GOPRIVATE только для рабочих проектов.

  • 17 апр.7 8456124

    👴 Почему в Go нет тернарного оператора? https://dburov.com/ru/research/go-ternary Дмитрий Буров провёл большое исследование на эту старую добрую тему и попросил меня поделиться ей, чтобы собрать мнение сообщества — внизу статьи есть короткий опрос из 4 вопросов. Вкратце, о чём материал: - Позиция core-команды Go не менялась с 2009 года: ?: порождает непроницаемо сложные выражения, if-else «бесспорно яснее», языку нужна только одна конструкция управления потоком - Проблема в том, что эта позиция никогда не подкреплялась реальными данными — только мнением авторов языка. Каждый новый proposal с 2019 года закрывается ссылкой на FAQ без содержательного разбора - Дмитрий написал статический анализатор и прогнал 4 крупных репозитория: golang/go, kubernetes, terraform, traefik - Нашёл 22 000+ паттернов, которые однозначно заменяются плоским тернарником (условный return, условное присваивание, раздутый конструктор, inline-выражение) - От 10% до 16% функций содержат хотя бы один такой паттерн. То есть каждая 6-9 функция И главный аргумент автора: команда Go запрещает оператор целиком из-за того, что его можно использовать во вложенном виде и получить нечитаемую кашу. Но другие языки давно решили эту проблему иначе — оставили сам оператор, а запретили именно вложенность: в JS через ESLint-правило no-nested-ternary, в C++ через clang-tidy, в PHP 8 вложенный ?: без скобок стал ошибкой компиляции. Go мог бы сделать то же самое через go vet, не лишая разработчиков плоских однострочников. ———— Тема холиварная, поэтому Дмитрию особенно важно собрать мнения — как тех, кто «за», так и тех, кто «против». Выборка заведомо смещена (сюда придут неравнодушные), но цель не в репрезентативности, а в том, чтобы проверить: совпадают ли представления команды Go о восприятии этих паттернов с тем, что говорят сами разработчики. В общем, предлагаю ознакомиться и выразить своё мнение. #article #research

  • 22 мар.9 33359251

    🟦 ❤️ Modern Go Guidelines от GoLand Team — чтобы AI-агенты перестали писать устаревший Go https://github.com/JetBrains/go-modern-guidelines Ребята из JetBrains сделали набор гайдлайнов для AI-агентов (Claude Code и Junie), чтобы те писали современный Go, а не код образца 2018 года. Проблема реальная и знакомая каждому, кто пользуется ИИ-ассистентами для Go: - Отсечка данных: модели не знают фичи, добавленные после их обучения. Claude Opus 4.6 обучен по май 2025 — про Go 1.26 он не в курсе. - Частотный перекос: в тренировочных данных в разы больше for i := 0; i < n; i++, чем for i := range n. Модель выбирает то, что встречала чаще. В результате агент вместо slices.Contains(roles, role) пишет ручной цикл на 7 строк, вместо new("hello") городит s := "hello"; &s, а про errors.AsType[T] вообще не слышал. Что делает плагин: - Определяет версию Go из go.mod - Инструктирует агента использовать фичи только до этой версии включительно - Покрывает всё от Go 1.0 до 1.26: cmp.Or, min/max, wg.Go(), b.Loop(), strings.SplitSeq, new(val) и т.д. Как подключить: - В Junie (GoLand) — работает из коробки начиная с версии 2xx.620.xx - В Claude Code — ставится как плагин, активируется командой /use-modern-go 🟢Ребята из GoLand Team протестировали его на 40 примерах и убедились, что без гайдлайнов Claude Code пишет откровенно устаревший код. ———— А что на счёт go fix? Как мы помним, в Go 1.26 полностью переписали go fix. Теперь это мощный инструмент с 20+ анализаторами-модернизаторами 👍 minmax, rangeint, slicescontains, stringscut, mapsloop, forvar, newexpr и другие. Одна команда go fix ./... — и ваш код автоматически переписывается на современные идиомы. Go Team сами признались, что LLM-ассистенты — одна из причин, почему они взялись за modernize-анализаторы. Чтобы в тренировочных данных было больше современного кода, нужно сначала модернизировать существующий. Так решает ли go fix ту же задачу? Частично — да. Если ваш агент написал for i := 0; i < n; i++ вместо for range n, go fix это подчистит. Но есть нюанс: go fix работает постфактум с уже написанным кодом, а гайдлайны JetBrains заставляют агента писать правильно с самого начала. Это два дополняющих друг друга подхода: один — «пиши сразу нормально», другой — «подстрахуем на всякий случай». Мой совет: подключайте гайдлайны + гоняйте go fix после каждого обновления тулчейна. Ну или, как один из комментаторов на HN предложил, добавьте golangci-lint с modernize-линтером в CLAUDE.md — пусть агент сам за собой убирает. 🟠Важно! Проект свежий и полностью открытый, любой вклад приветствуются — можно добавлять поддержку других агентов, новые правила и любые улучшения. Ребята из GoLand Team будут только рады. Мне об этом лично сказали. #ai #tools

  • 6 мар.7 7083313

    🔨 Два активных proposal с жаркой дискуссией Proposal #1: Вернуть go mod init к здравому смыслу В Go 1.26 тихо поменяли поведение go mod init: теперь он выставляет в go.mod директиву go 1.25 вместо go 1.26. Идея была в том, чтобы новый модуль был "по умолчанию…

  • 3 мар.7 7193923

    🔨 Два активных proposal с жаркой дискуссией Proposal #1: Вернуть go mod init к здравому смыслу В Go 1.26 тихо поменяли поведение go mod init: теперь он выставляет в go.mod директиву go 1.25 вместо go 1.26. Идея была в том, чтобы новый модуль был "по умолчанию совместим" со старыми тулчейнами. Проблема в том, что это ломает ожидания: $ go version go version go1.26 $ go mod init myproject # go.mod теперь содержит: go 1.25 $ go build ./main.go: new(42) requires go1.26 or later То есть читаешь про новые фичи Go 1.26, устанавливаешь его, создаёшь новый проект — и получаешь ошибку! Потому что go mod init тайком выставил тебе прошлую версию 😡 Автор proposal (и большинство комментаторов) считают это контринтуитивным: если хочешь поддерживать старые версии — осознанно понизь директиву сам. По умолчанию же должна быть версия твоего тулчейна. Аргумент Go Team: "это полезно для совместимости при публикации модуля". Контраргумент: forward compatibility в тулчейне уже решает эту проблему — если нужная версия не установлена, Go скачает её сам. ———— Proposal #2: UUID в стандартной библиотеке Предложение добавить crypto/uuid в stdlib. Открыто ещё в августе 2023 (!!), обсуждение до сих пор живое. Аргументы за очевидны: UUID нужен в каждом втором сервисе, google/uuid — один из самых популярных импортов в Go-проектах, и практически все языки уже имеют UUID из коробки — C#, Java, Python, JavaScript, Ruby. Go — исключение. Статус в Proposal Projects — "Likely Accept", то есть Go Team склоняется к тому, чтобы принять. Шансы появления UUID в stdlib довольно высокие. ———— Мне тут даже комментировать нечего — решение про go mod init считаю крайне странным, надо вернуть его в норму. Представьте лицо новичка в Go, который впервые создал проект 😄 🟢В списке релизов уже можно видеть, что в Go 1.26.1 это поведение откатят Добавить генерацию UUID в stdlib давно пора. Если подытожить, оба proposal отражают одно и то же: Go бережёт обратную совместимость и осторожничает с расширением stdlib — иногда в ущерб удобству разработчика. #proposal #go1_26

  • 27 февр.8 4905376

    🧬 Proposal: Generic Methods для Go Robert Griesemer (один из авторов языка) открыл proposal, который многие считали невозможным. Go FAQ буквально говорил: > We do not anticipate that Go will ever add generic methods Но теперь — возможно, добавят 👍 Суть…

  • 23 февр.8 208103

    🧬 Proposal: Generic Methods для Go Robert Griesemer (один из авторов языка) открыл proposal, который многие считали невозможным. Go FAQ буквально говорил: > We do not anticipate that Go will ever add generic methods Но теперь — возможно, добавят 👍 Суть…

  • 23 февр.9 8584743

    🧬 Proposal: Generic Methods для Go Robert Griesemer (один из авторов языка) открыл proposal, который многие считали невозможным. Go FAQ буквально говорил: > We do not anticipate that Go will ever add generic methods Но теперь — возможно, добавят 👍 Суть в том, что раньше дженерик-методы блокировались по цепочке: если методы могут принимать параметры типов, значит и методы интерфейсов тоже должны. А это не знали как реализовать эффективно — в Go тип реализует интерфейс неявно, поэтому компилятор не может знать заранее, для каких конкретных типов нужно будет скомпилировать метод. Ключевой сдвиг в мышлении: метод — это не только способ реализовать интерфейс. Метод — это функция, привязанная к типу, удобная для организации кода и читаемая слева направо. Эти две вещи ортогональны. Поэтому компромисс такой: методы могут быть generic, но не могут реализовывать интерфейсы с generic методами — их просто не будет. Вот как это выглядит: type Reader struct{ … } func (*Reader) Read[E any]([]E) (int, error) { … } Reader не реализует io.Reader — и это нормально. Зато метод полезен сам по себе. При этом изменение полностью обратно совместимо и не закрывает возможность добавить такое в будущем, если придумают как. ———— Дискуссия горячая — 156 комментариев. Кто-то радуется, кто-то боится усложнения языка, классика. За то и люблю наше сообщество ✨ Я сам редко работаю с дженериками, но при этом даже я не раз сталкивался с этим ограничением. Приходится делать standalone функции вместо методов — цепочки вызовов ломаются, читаемость страдает. За я или против? Честно, не знаю — вопрос действительно непростой, если вникать глубоко в проблематику и доводы обоих сторон. Поэтмоу я предпочитаю делегировать столь сложные вопросы бородатым мужчинам — я в них верю! ❤️ Посмотрим, примут ли. Но сам факт, что Griesemer это открыл — уже хороший сигнал. #proposal #generics

  • 22 февр.5 34210493из tuzov_ai_lab

    😩 Go Team vs вайбкодеры https://groups.google.com/g/golang-dev/c/4Li4Ovd_ehE Кто-то залил CL (changelist, аналог Pull Request в системе Gerrit) в Go с тегом Co-Authored-By: Claude Opus 4.5 в описании коммита. Ian Lance Taylor это заметил и поднял вопрос в рассылке golang-dev: а вообще есть ли политика по поводу AI-написанного кода? Авторские права, CLA — всё это висит в воздухе. Ответ Rob Pike: > Это очень скользкая дорожка. Осторожнее с первым шагом. Рекомендую просто сказать: нет. Через несколько дней Russ Cox написал огромный взвешенный ответ. И это, пожалуй, лучший текст о месте AI в разработке, что я читал за последнее время. Рекомендую вам ознакомиться с ним целиком лично. Самый сочный кусок — про "танцующих слонов": > Люди хвастаются кодовыми базами на сотни тысяч строк, которые никто никогда не смотрел, написанными в рекордные сроки. При ближайшем рассмотрении они неизменно оказываются скорее танцующими слонами, чем полезными engineering-артефактами. То есть, они впечатляют, но только пока не присмотришься — слишком большие, медленные, много багов, и никто не знает как их поддерживать. Его позиция: фундаментальные вещи software engineering не изменились. AI — это инструмент, как редактор или профайлер. Можно писать качественный код с помощью AI, но только если не отключать мозг. Контрибьютор всё так же обязан присылать код, который он сам проревьюил и обдумал — AI не снимает с тебя ответственности. По авторским правам: Google's OSPO разобрался, используйте спокойно. Но интересно другое: Alan Donovan в треде заметил, что значительная часть CLs уже содержит LLM-сгенерированный код — авторы просто не признаются. По Co-Authored-By — убрать. Причина прямолинейная: это бесплатная реклама AI-компаниям, и ничего больше. Юридически строчка бессмысленна (AI не может быть автором по US copyright), информации не несёт — непонятно кто что написал, и даже как маркер использования AI не работает: модель сама непоследовательно решает, добавлять её или нет. ———— Позиция Russ Cox мне близка, т.к. я лично сталкивался с подобными случаями даже на работе — когда разработчик перегибал с вайбкодингом. Работать с этим становится невозможно, проще переписать с нуля. "Танцующие слоны" — это хорошее описание того, что происходит когда люди воспринимают AI как замену мышлению, а не как инструмент. Go team явно не собирается идти по этому пути ❤️ #goteam #llm #claude

  • 21 февр.7 3885987

    Обещают в ближайших постах в блоге рассказать больше о новом go fix и как оно работает внутри

  • 21 февр.6 67540162

    Пишем JSON-парсер с нуля на Go https://sushantdhiman.dev/lets-write-a-json-parser-from-scratch/ Sushant Dhiman разбирает, как написать JSON-парсер с нуля — от токенизации до AST. Статья небольшая, но хорошо структурированная. Два основных этапа: Токенизатор — проходит по строке посимвольно и разбивает её на токены: {, "key", :, 123 и т.д. Отдельно обрабатываются строки (с учётом экранирования), числа, литералы true, false, null. Парсер — принимает токены и строит AST. Каждый узел — отдельный тип (StringNode, ObjectNode, ArrayNode и т.д.), всё через рекурсивный parseValue. В конце задачка: попробуй преобразовать AST в нативные Go-структуры и использовать их. Неплохо для закрепления. ———— Традиционно люблю статьи «напиши X с нуля» — они хорошо прокачивают понимание внутреннего устройства привычных инструментов. Джэйсоны мы гоняем каждый день, даже не задумываясь что там внутри, а внутри всё хитро и интересно 👍 Код несложный, читается легко, исходники на GitHub. #article #diy #parsing #ast

  • 12 февр.6 5284447из go_update

    🎉 Вышел Go 1.26! 🎉 Не получилось написать об этом день в день, поэтому пишу на следующий день. Ключевое из релиза: • Функция new теперь принимает не только типы, но и обычные аргументы. Т.е. раньше можно было писать new(int), а теперь станет возможным ещё и new(42). Использовать в качестве замены &MyStruct{…} (т.е. new(MyStruct{…}) не рекомендую, тк генерирует менее производительный код. Подробно про новую поведение функции я писал тут. • Type-parameters в типах теперь могут ссылаться сами на себя: type Adder[A Adder[A]] interface { Add(A) A } Это довольно техническое изменение, которое позволит авторам библиотек со всякими коллекциями лучше выражать требования к типам от пользователя. Если вы не сталкивались с этой проблемой, значит вы счастливый человек и для вас ничего не поменяется. • go fix полностью переделали: теперь он модернизирует код, заменяя устаревшие конструкции более современными. Перед тем как применять можно глянуть diff через go fix -diff. Из интересного: с помощью управляющего комментария //go:fix inline над функцией можно заменить её вызов на её тело по коду в автоматическом режиме. Обещают в ближайших постах в блоге рассказать больше о новом go fix и как оно работает внутри. • go mod init при создании нового модуля теперь выставляет версию Go 1.N-1 где N это версия, бинарь которой вы вызываете. Т.е. при вызове на компиляторе go 1.26.0 в go.mod будет выставлено go 1.25.0. Говорят, что сделано для улучшения обратной совместимости внутри экосистемы: чтобы больше людей писало код который будет работать на всех поддерживаемых версиях компилятора. • Green Tea сборщик мусора теперь является основным. Обещают снижение затрат на сборщик мусора от 10 до 40 процентов, и еще 10 сверху если используете новые amd64 процессоры типо Ice Lake и Amd Zen 4. Я так и не назрел написать статью про новый сборщик, тк пока я размышлял об этом, ребята сами написали отличный пост в блоге с картинками и видео. Рекомендую, там много интересных деталей. • Оверхед на вызов функций через CGO теперь меньше на 30 процентов. В практических терминах это значит, что sqlite стал ещё быстрее. • Адрес начала хипа теперь случайный на 64 битных платформах. Если вам это не о чем не говорит, даже не заморачивайтесь 😄. • Экспериментальный профилировщик для «утекших» горутин. Мега крутая фича которую завезли ребята из Uber (параллельно написав научную статью). Поиграться можно вот тут. Фича полностью production ready хотя и активируется с помощью флага GOEXPERIMENT=goroutineleakprofile во время сборки. Причина: хотят собрать фидбэк перед финализацией API. • Новый пакет simd/archsimd для тех кто работает с большими массивами числовых данных. Спрятан за флагом GOEXPERIMENT=simd. • Новый пакет runtime/secret для тех кому есть, что скрывать кто работает с криптографией. Подробнее писал тут. Скрыт за флагом GOEXPERIMENT=runtimesecret. • Новая дженерик функция errors.AsType на замену errors.As. Теперь можно писать pathError, ok := errors.AsType[*fs.PathError](err) Подробнее писал тут. • fmt.Errorf("x") теперь аллоцирует столько же, сколько и errors.New("x"), поэтому у вас меньше поводов делать этот рефакторинг. • Новый флаг -artifacts для go test позволяет настроить каталог для хранения артефактов (файлов которые должны пережить конец тестирования). Сам каталог доступен через T.ArtifactDir и компанию. • Разные оптимизации подъехали. Из трендов: язык явно ускоряется в своей эволюции, поэтому на помощь программистам подтягивают тулинг (go fix) который позволит оставаться «в контексте». Но шестимесячного цикла, ребятам отвечающим за компилятор и библиотеку, явно не хватает и поэтому много вещей находятся за экспериментальными флагами. Получается классическая дилемма регулярных релизов: либо тащить условно готовые вещи, либо регулярно срывать сроки. И судя по другим предложениям которые находятся в статусе likely accept следующий релиз вероятно будет не меньше.

  • 11 февр.6 4685562из deferpanic

    Вышел Go 1.26. Релиз с виду небольшой, но интересный: • в new можно теперь передавать выражения • go fix теперь запускает модернайзеры — тулы для авто-исправления кода согласно новым стандартам (например, замена strings.Split на итератор strings.SplitSeq внутри for-range). Обещают позже раскрыть больше подробностей в блоге • новый сборщик мусора теперь включен по умолчанию • pprof научился находить утекшие горутины

  • 24 янв.9 1435039из go_update

    😳😳 proposal: spec: generic methods for Go 😳😳 Я не так часто пишу тексты в выходные, но тут случилось исключение, которое я не ожидал увидеть от слова «совсем»: Go Team (а именно Роберт Гризмер, один их трех «столпов» Go) предлагает добавить в язык дженерик методы. Тут надо сделать отступление: просьбы об этом от сообщества шли давно. Невозможность иметь дженерик методы существенно усложняла часть кода и делала невозможными «поточные» типы. Но сами просьбы разбивались о взаимодействие интерфейсов и дженерик методов у типов: настолько часты были эти просьбы и ответное разъяснение, что в Go FAQ есть специальный пункт про это, который я очень рекомендую прочитать что-бы осознать суть (и глубину) проблемы. We do not anticipate that Go will ever add generic methods Так что-же поменялось? Ну во первых «запрос о добавлении дженерик методов в Go» один из самых популярных. 49085 набрало больше 900 положительных emoji, а вопрос «как сделать дженерик методы в Go» остается одним из самых популярных на профильных ресурсах. Во вторых сам Роберт предполагает, что изначальная постановка о дуализме «методы <-> интерфейсы» может быть неверна. В чем суть нового предложения? По сути предлагается разрешить следующую запись: type S struct { ... } func (*S) m[P any](x P) { ... } type G[P any] struct{ ... } func (*G[P]) m[Q any](x Q) { ... } Да-да, теперь можно написать те самые Type[In any].Map[Out any] методы к которым привыкли программисты из С++/Java|C#. При этом эти методы обладают двумя значимыми ограничениями: Они не реализуют интерфейс даже при совпадении имени и сигнатуры. type I interface { m(int) } type H struct{ … } func (H) m[P any](P) { … } var h H var _ I = h // ошибка: сигнатура H.m где m[P any](P) не удовлетворяет m(int) типа I Пример который более приближен к реальности type Reader struct{ … } func (*Reader) Read[E any]([]E) (int, error) { … } Не удовлетворяет io.Reader даже если в коде есть вызовы (*Reader).Read[byte]. Их нельзя «увидеть» с помощью пакета reflection. Так как инстанцирование методов происходит во время компиляции, рантайм банально не знает как «увидеть» этот метод динамически. И вызвать его тоже не может. Сам proposal прописывает довольно много технических подробностей и необходимую работу внутри компилятора (которой, на удивление, относительно немного). Но главное тут другое: основная мотивация это удобство записи: x.a().b().c() писать легче чем c(b(a(x)) и отсутствие дженерик методов существенно усложняет процесс портирования streaming типов из других языков. Насколько хороша эта мотивация покажет время, но тот факт, что автором предложения является один из оригинальных авторов языков, а так-же то, что предложение (на данный момент) позитивно принято сообщество (400+ позитивных emoji) наводит на мысль, что проблема действительно актуальна. P.S: оригинальный proposal про дженерики содержал такой параграф. Or, we could decide that parameterized methods do not, in fact, implement interfaces, but then it's much less clear why we need methods at all. If we disregard interfaces, any parameterized method can be implemented as a parameterized function. Те авторы уже изначально закладывали вариант, что могут и передумать. Ну вот и передумали. 😁️️️️️️

  • 12 янв.8 1244873из thank_go

    Интерактивный тур по 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

  • 30 дек.6 79934110из ntuzov

    👴 Как учиться разработчику и почему ты делаешь это неправильно https://youtu.be/EgnRsIJiuxc Юбилейный выпуск 20-й выпуск GoGetPodcast! Самую вкусную тему откладывал специально для этого случая. Три с половиной часа я изучал мозги двух крутых экспертов — Глеба Яльчика и Алексея Акуловича, пытаясь понять, как мне хотя бы приблизиться к их уровню 🌚 Разговор получился очень крутой, именно поэтому он настолько растянулся. Что обсудили: - Протокол погружения: как за 48 часов разобраться в новой сложной теме? Гугл? Дока? Ютуб с индусами? Звонок другу? - Теория vs практика: когда читать книгу бесполезно, а когда — необходимо. Как Глеб научился программировать за 90 минут, а до этого целый семестр ничего не понимал - Трансформация информации: почему просто прочитать недостаточно. Нужно практиковать, объяснять другим, перефразировать — и как это правильно делать - Золотой фонд: nand2tetris, Deadlock Empire, "Код" Петцольда, Effective Go, спецификация языка — что из этого реально нужно и когда - Алгоритмы и LeetCode: стоит ли реализовывать красно-чёрные деревья своими руками? Нужен ли LeetCode вообще? - Оверинжиниринг pet-проектов — Холивар: можно ли научиться хайлоаду, искусственно создавая нагрузку? Тут наши мнения разошлись. - Метод Фейнмана на практике: почему лучший способ научиться — это научить кого-то другого Это не мотивационный разговор в стиле "учиться полезно". Это конкретные методы обучения, даже если гости сами их не осознают 🌚 ———— 🫶 Этот выпуск вышел при поддержке AvitoTech Да, выпуски теперь выходят один за одним! Это не совпадение — можете поблагодарить нашего спонсора, это их заслуга ❤ К слову, у ребят из AvitoTech тоже есть интересные материалы и ресурсы для вас: - Видео-обзор новых фишек Go - YouTube-канал с материалами для разработчиков - Митапы #gogetpodcast #обучение

  • 28 дек.6 4792362

    weak.Pointer в Go 1.24: слабые указатели для автоматической очистки кешей https://victoriametrics.com/blog/go-weak-pointer/ Статья VictoriaMetrics про пакет weak, который появился в Go 1.24. А в пакете том слабые указатели (weak pointers), которые не мешают сборщику мусора удалять объекты. 🟢Простыми словами: суть в том, что обычный указатель удерживает объект в памяти (strong reference), а слабый — нет. GC считает объект "мусором", если на него остались только слабые указатели. Проблема стара как мир: - Храним объекты в кеше/словаре — они никогда не удаляются - Приходится руками управлять временем жизни через TTL, LRU и прочие костыли - Забыли почистить — утечка памяти Классический выбор: либо утечка, либо сложная логика очистки. Решение — weak.Pointer: - Создаёшь через weak.Make(ptr) - Получаешь объект через ptr.Value() — если GC ещё не удалил, вернёт объект, иначе nil - GC может удалить объект в любой момент, даже если weak.Pointer существует Пример использования: type Cache struct { mu sync.Mutex items map[string]weak.Pointer[Value] } func (c *Cache) Get(key string) *Value { c.mu.Lock() ptr := c.items[key] c.mu.Unlock() return ptr.Value() // nil, если GC уже удалил } Важные нюансы: - Value() может вернуть nil очень рано — в последней точке использования (last point of use) объекта, даже если он ещё физически в памяти - Для tiny / pointer-free объектов (вроде *int) Value() может вообще никогда не обнулиться из-за упаковки в рантайме - Сам weak.Pointer не чистит map — ключи останутся, просто значения станут nil. Для автоудаления записей нужен runtime.AddCleanup ———— Честно говоря, пока не придумал, где бы мне это пригодилось в продакшене. Обычно я либо явно контролирую время жизни объектов, либо использую готовые LRU-кеши. Но концепция интересная — в некоторых сценариях (кеш запросов, мемоизация) может убрать ненужную сложность. Официальный пример от Go Team как раз про кеш memory-mapped файлов — там weak.Pointer + AddCleanup позволяют ядру самому решать, когда выгружать данные. В общем, nice to have, но не game changer. Для большинства задач старые добрые sync.Map и time.AfterFunc справляются отлично. #go1_24 #memory #gc

Golang Дайджест — tgindex