Thank Go!
Open in Telegram
Неожиданный взгляд на язык программирования Golang. Конструктив от @mikeberezin с нотками сарказма от @nalgeon
Show more1 297
Subscribers
No data24 hours
No data7 days
No data30 days
Data loading in progress...
Similar Channels
No data
Any problems? Please refresh the page or contact our support manager.
Tags Cloud
No data
Any problems? Please refresh the page or contact our support manager.
Incoming and Outgoing Mentions
---
---
---
---
---
---
Attracting Subscribers
September '24
September '24
+488
in 0 channels
August '240
in 0 channels
Get PRO
July '240
in 0 channels
Get PRO
June '240
in 0 channels
Get PRO
May '24
+9
in 0 channels
Get PRO
April '24
+44
in 0 channels
Get PRO
March '24
+39
in 0 channels
Get PRO
February '24
+52
in 0 channels
Get PRO
January '24
+38
in 0 channels
Get PRO
December '23
+37
in 0 channels
Get PRO
November '23
+58
in 0 channels
Get PRO
October '23
+39
in 0 channels
Get PRO
September '23
+39
in 0 channels
Get PRO
August '23
+46
in 0 channels
Get PRO
July '23
+62
in 0 channels
Get PRO
June '23
+46
in 0 channels
Get PRO
May '23
+62
in 0 channels
Get PRO
April '23
+43
in 0 channels
Get PRO
March '23
+43
in 0 channels
Get PRO
February '23
+56
in 0 channels
Get PRO
January '23
+111
in 0 channels
Get PRO
December '22
+53
in 0 channels
Get PRO
November '22
+71
in 0 channels
Get PRO
October '22
+53
in 0 channels
Get PRO
September '22
+50
in 0 channels
Get PRO
August '22
+41
in 0 channels
Get PRO
July '22
+75
in 0 channels
Get PRO
June '22
+22
in 0 channels
Get PRO
May '22
+13
in 0 channels
Get PRO
April '22
+75
in 0 channels
Get PRO
March '220
in 0 channels
Get PRO
February '220
in 0 channels
Get PRO
January '220
in 0 channels
Get PRO
December '210
in 0 channels
Get PRO
November '210
in 0 channels
Get PRO
October '210
in 0 channels
Get PRO
September '210
in 0 channels
Get PRO
August '210
in 0 channels
Get PRO
July '210
in 0 channels
Get PRO
June '210
in 0 channels
Get PRO
May '210
in 0 channels
Get PRO
April '210
in 0 channels
Get PRO
March '21
+5
in 0 channels
Get PRO
February '21
+4
in 0 channels
Get PRO
January '21
+5
in 0 channels
Get PRO
December '20
+371
in 0 channels
| Date | Subscriber Growth | Mentions | Channels | |
| 25 September | 0 | |||
| 24 September | +4 | |||
| 23 September | +3 | |||
| 22 September | 0 |
Channel Posts
Go 1.22
Вчера вышел Go 1.22 с интересными фичами:
— Починили багу с замыканием счетчика цикла (большое дело!)
— Цикл for range заработал по числам (прямо как в питоне)
— Новый пакет для генерации случайных чисел math/rand/v2
— Роутинг с поддержкой переменных в http (наконец-то)
Вместо сухих официальных релиз нотсов можно читать мои интерактивные с примерами.
| 2 | Замыкание = гибкость
Замыкания в Go используются повсеместно. Они позволяют универсально использовать один и тот же инструмент для работы в разных ситуациях.
Вот, например, карта в пакете sync — sync.Map:
var m sync.Map
m.Store("alice", 11)
m.Store("bob", 12)
m.Store("cindy", 13)
Чтобы проитерироваться по карте, предусмотрен метод Range с такой сигнарутой:
Range(f func(key, value any) bool)
Но что делать, если мы хотим просуммировать все значения карты? Кажется, Range не дает такой возможности. Придется переписать все на питон.
Ну или использовать замыкание:
total := 0
m.Range(func(key, value any) bool {
total += value.(int)
return true
})
Анонимная функция, переданная в Range, использует внешнюю переменную total как накопитель. Таким образом можно реализовать вообще любое поведение, не трогая сигнатуру Range.
Полезная штука. | 1 125 |
| 3 | Как писать декораторы? | 1 333 |
| 4 | Декораторы
Мой знакомый Редован поднял вопрос организации повторных попыток (retries) в Go.
Это интересная тема, потому что ретраи — частный случай декораторов, которые на практике встречаются постоянно (мидлвари, транзакции или аудит тоже удобно делать через декораторы).
В заметке он предлагает на выбор два подхода — рефлексию или дженерики.
Мне не нравятся оба. Предпочитаю использовать замыкания, потому что с ними код проще и понятней.
А вы что думаете? (опрос следует) | 1 335 |
| 5 | Значение ↔ указатель
Если метод определен на значении, его можно вызывать и на указателе:
type Cat struct{}
func (c Cat) Meow() {}
val := Cat{}
val.Meow()
ptr := &Cat{}
ptr.Meow()
песочница
И наоборот:
type Cat struct{}
func (c *Cat) Meow() {}
val := Cat{}
val.Meow()
ptr := &Cat{}
ptr.Meow()
песочница
Дело усложняется, когда переменная имеет не конкретный тип, а интерфейсный.
Работает почти всегда, кроме одной ситуации: метод определен на указателе, а интерфейсной переменной присваивают значение:
type Meower interface {
Meow()
}
type Cat struct{}
func (c *Cat) Meow() {}
var ival Meower
ival = Cat{}
Здесь будет ошибка: Cat does not implement Meower (method Meow has pointer receiver)
Подробности в go-вики | 1 201 |
| 6 | Многозадачность: примитивы синхронизации
На курсе «Многозадачность в Go» вышли три новых урока!
В них вы:
— Досконально разберетесь с группами ожидания.
— Научитесь ловить гонки и защищаться от них с помощью мьютексов.
— Освоите семафоры, рандеву и барьеры.
P.S. Помню, что обещал закончить курс еще в прошлом году, а он все никак. Если вы передумали проходить и хотите вернуть деньги — пишите в личку.
https://stepik.org/a/133280 | 1 351 |
| 7 | Так можно? go go func() {}() | 1 668 |
| 8 | Go 1.22: интерактивные заметки к релизу
Release notes в Go традиционно сухие как прошлогодние сухари, а я люблю разбирать все новое на примерах.
Поэтому решил оживить заметки к релизу 1.22 (выйдет в феврале) и добавил в них интерактивных примерчиков, чтобы вы могли попробовать новые фичи уже сейчас, прямо из браузера.
https://antonz.org/go-1-22 | 1 400 |
| 9 | Структура проекта в Go
Любимое развлечение го-разработчиков — спорить о правильной структуре проекта. Вот и авторы Go наконец решили высказаться (очень вовремя, всего-то 6 лет прошло с момента появления модулей).
Вкратце:
— Для мелких проектов — плоская структура без каталогов.
— Для более крупных — каталог internal с вложенными пакетами, публичные пакеты только при необходимости.
— Каталог cmd — когда в проекте несколько команд.
Что делать с прочими артефактами помимо кода (вроде документации и инфраструктуры) — скромно умолчали.
https://go.dev/doc/modules/layout | 849 |
| 10 | 2. Сигнатура
Функция Clone должна работать со срезами любых типов (срезы чисел, строк, структур итп), а также с типами, образованными от срезов (когда мы пишем собственный тип, используя срез в качестве базового).
То есть функция должна принимать тип S, который либо сам по себе срез ([]E), либо образован от среза (~[]E), а тип элемента среза при этом не важен (E any). На птичьем языке дженериков в Go получается S ~[]E, E any.
Такие дела. | 752 |
| 11 | 1. Копирование
Можно было бы вернуть просто s[:]. Но это была бы поверхностная (shallow) копия — так скопируется срез, а массив под ним окажется тем же, что был. Поэтому изменяя копию среза, изменим и оригинальный массив.
Конструкция s[:0] создает срез нулевой длины (zero-length), который все еще ссылается на оригинальный массив. А s[:0:0] создает срез нулевой вместимости (zero-capacity), который ссылается на новый (пустой) массив.
Поэтому, когда мы добавляем к клону элементы оригинального s — они попадают в новый массив. Это и обеспечивает глубокое копирование. | 650 |
| 12 | Довольно простая функция: разбор
Вот функция, простотой которой наслаждается Ян:
func Clone[S ~[]E, E any](s S) S {
return append(s[:0:0], s...)
}
Она выполняет глубокое (deep) копирование среза s: клонирует не только сам срез, но и массив под ним (как вы помните, срез — это легковесная структура, которая сама по себе не содержит данных, а содержит ссылку на массив).
Легкую оторопь тут могут вызвать два момента: само копирование и сигнатура функции. Разберем оба. | 647 |
| 13 | Простая или непростая? | 739 |
| 14 | Довольно простая функция
Ян Ланс Тейлор (один из авторов Go) считает, что это довольно простая функция:
func Clone[S ~[]E, E any](s S) S {
return append(s[:0:0], s...)
}
А вы как считаете? (опрос следует) | 815 |
| 15 | Довольно простая функция
Ян Ланс Тейлор (один из авторов Go) считает, что это довольно простая функция. А вы как считаете? ```func Clone[S ~[]E, E any](s S) S { return append(s[:0:0], s...) }``` https://go.dev/blog/deconstructing-type-parameters | 2 |
| 16 | Go ♡ SQLite
Тут добрый человек Riyaz Ali сделал Go-модуль с набором полезных расширений SQLite:
— кодирование/декодирование
— динамический SQL
— работа с файлами
— текстовые функции
— IP адреса
— мат. статистика
— UUID
— CSV
Если вы, как и я, неравнодушны SQLite — рекомендую!
https://github.com/riyaz-ali/sqlean.go
P.S. Небольшой анонс, чтобы два раза не писать. В сентябре возвращаюсь к курсу «Многозадачность в Go», так что если вдруг переживали за его судьбу — не переживайте ツ | 1 012 |
| 17 | Пишем менеджер пакетов на Go
Как-то так вышло, что я написал менеджер пакетов на Go. А поскольку задачка оказалась интересной — подробно описал архитектуру и детали реализации.
Так что если вам интересно посмотреть, как темы курса Thank Go! применяются на практике — рекомендую.
Вот какие темы нашли применение в проекте:
1) Все из модуля «Основы», от базовых типов до интерфейсов и ошибок.
2) Пакеты, модули и тесты.
3) Работа с текстом.
4) Работа с файлами.
5) JSON.
6) HTTP.
Исходники тоже доступны, разумеется.
А еще там комментарии и тесты на каждый файл, благодать. Когда еще такое встретишь!
https://antonz.ru/writing-package-manager/ | 1 551 |
| 18 | 📝 Узнаем больше о Go разработке
Ребята из DevCrowd (а они же основатели классного подкаста Podlodka) проводят исследование Go-разработчиков:
- Какие навыки для go-разработчиков самые важные
- Какие инструменты используются в работе
- Как попадают в профессию и куда из нее уходят
- Полезные для развития каналы, курсы и книги
Результаты будут в открытом доступе, а значит это отличный шанс узнать больше об индустрии.
Опрос довольно большой, но интересный. Мне потребовалось 10 минут, чтобы вдумчиво его пройти.
Давайте поучаствуем!
Пройти опрос | 1 814 |
| 19 | Наш отдел дата-аналитики трудился не покладая рук, и подготовил ИНФОГРАФИКУ. | 2 008 |
| 20 | Пока в комментариях идет битва за clear, отвечу на вопрос из посткриптума:
Зачем делать встроенные min и max вместо дженерик-функций
Ответ существует, но вам он не понравится. Процитирую авторов языка (с сокращениями):
We have gone back and forth a few times on this proposal about min/max being builtins vs being in package cmp.
There are good arguments on both sides. On the one hand, min and max are fundamental arithmetic operations much like addition, which justifies making them builtins.
On the other hand, we have generics now and it would make sense to use generics to write library code rather than make them builtins.
Even among the active Go language designers, our own personal intuitions differ on this.
полный ответ
🤷♀️ | 1 600 |
