PRO Go
3.6K subscribers
304 photos
82 videos
198 links
Изучай язык Go вместе с нами.

Закрепить теорию на практике можно на бесплатном курсе https://clck.ru/36mYmG

По всем вопросам:
@Santiago_de
Download Telegram
🤓Ошибка — дело привычки Go остаётся верен себе:
— синтакс для обработки ошибок не упростят — новые предложения даже рассматриваться не будут.


С 2018 года команда пыталась: — check/handle try(...) — даже ?, как в Rust
Итог: три своих предложения, сотни от комьюнити — и ни одно не получило общего одобрения. После стольких итераций архитекторы Go говорят прямо:
> "We should stop trying to solve the syntactic problem, at least for the foreseeable future."

if err != nil — это не баг. Это стиль. Go остаётся многословным — потому что предсказуемость важнее лаконичности.

Ссылка на блог
Please open Telegram to view this post
VIEW IN TELEGRAM
👍76👀1
Когда вместе — даже баги замирают от уважения 💪
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
21🔥114
Media is too big
VIEW IN TELEGRAM
Как же здорово, когда вокруг люди, с которыми хочется свернуть горы! ⛰️

Три дня невероятной энергии, общих планов и моментов, которые хочется сохранить в памяти… ❤️

Этим роликом хочу передать вам частичку того, что мы пережили.
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍5🔥5
🤓 Слабые указатели

В версию go 1.24 🤓 добавили новый пакет weak, который позволяет создавать слабые указатели — ссылки на объекты, которые не мешают сборщику мусора освободить память.

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

📦 Пример:
wb := weak.Make(newBlob(1000)) // создаём слабый указатель на объект
fmt.Println("before GC =", wb.Value()) // объект ещё доступен

runtime.GC() // запускаем сборщик мусора

fmt.Println("after GC =", wb.Value()) // возможно, объект уже удалён → вернёт nil


Если объект больше не используется, wb.Value() может вернуть nil после сборки мусора.

Для сравнения, обычный указатель не даст объекту исчезнуть:
b := newBlob(1000)  // обычный указатель на объект
fmt.Println("before GC =", b) // объект доступен

runtime.GC() // запускаем сборщик мусора

fmt.Println("after GC =", b) // объект всё ещё в памяти — указатель его "удерживает"


🤡 Важно: нет гарантии, что объект исчезнет сразу после того, как стал недостижим. Рантайм сам решает, когда и что очищать.

#слабые #указатели
Please open Telegram to view this post
VIEW IN TELEGRAM
1104🔥3
🤓 Релиз Go 1.24.5 и 1.23.11!

🔐 Безопасность: включено исправление уязвимости в цепочке инструментов Go (CVE-2025-4674)

🤓 Анонс ❤️ Скачать
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥52
Go 1.25: Тесты без ожиданий

В релизе Go 1.25 наконец стабилизировали synctest — теперь можно использовать его без оглядки на экспериментальный статус.

Этот пакет пригодится тем, кто когда-либо писал тесты с time.Sleep, time.After, time.NewTimer и другими блокирующими операциями. synctest предоставляет виртуальные часы, которые сами идут вперёд, если тестируемая горутина ждёт.

Например, обычная функция:
func SlowThing() int {
start := time.Now()
time.Sleep(15 * time.Second)
fmt.Println("done in", time.Since(start))
return 7
}


Раньше её тест нужно было ждать 15 секунд. Теперь всё можно обернуть в synctest.Test — и проверка произойдёт мгновенно:
func TestSlowThing(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
if SlowThing() != 7 {
t.Error("unexpected result")
}
})
}


Результат:
=== RUN   TestSlowThing
done in 15s
--- PASS: TestSlowThing (0.00s)


#go1_25
8🔥42👍2
🤓 Go 1.25: тесты таймеров и select без задержек

Если вы когда-либо писали тесты с time.Sleep, time.After или time.Ticker, вы наверняка заметили, что на каждый «таймаут» уходит реальное время. В больших наборах тестов это может растянуть прогон CI до бесконечности.

Пакет synctest подменяет системные часы на «фейковые»: ваши тесты мгновенно прыгают вперёд, не ожидая 5 или 10 секунд.

Установите пакет:
go get github.com/your/repo/synctest


В тестах оборачивайте логику в synctest.Test:
synctest.Test(t, func(t *testing.T) {
// ваш код с таймерами
})


🤓 Select с time.After vs time.NewTimer
synctest.Test(t, func(t *testing.T) {
afterCh := time.After(5 * time.Second)
timer := time.NewTimer(10 * time.Second)

select {
case <-afterCh:
fmt.Println("after fired first")
case <-timer.C:
fmt.Println("timer fired first")
}
})


time.After(5s) возвращает канал, который сработает через 5 секунд.

time.NewTimer(10s) даёт канал, который сработает через 10 секунд.

Fake clock мгновенно перематывает на +5 секунд, и мы сразу видим after fired first, без реального ожидания.

🤓 Проверяем time.Ticker
synctest.Test(t, func(t *testing.T) {
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()

first := <-ticker.C
second := <-ticker.C

fmt.Println("ticks at:", first, second)
})


NewTicker(3s) запускает «тиковый» канал каждые 3 секунды.

Fake clock сразу делает два прыжка по 3 секунды, и оба чтения <-ticker.C выполняются без задержек.
Please open Telegram to view this post
VIEW IN TELEGRAM
182🔥2
PRO Go
🤓 Go 1.25: тесты таймеров и select без задержек Если вы когда-либо писали тесты с time.Sleep, time.After или time.Ticker, вы наверняка заметили, что на каждый «таймаут» уходит реальное время. В больших наборах тестов это может растянуть прогон CI до бесконечности.…
🔥 Как работает синтетическое время в Go 1.25?

⚙️ Пузырь и виртуальные часы. Когда вы вызываете synctest.Test(...), создается изолированный пузырь — тестовую среду с отдельными часами. Эти часы:

🕒 не идут сами по себе — они стоят на месте 💪 двигаются только тогда, когда все горутины внутри пузыря заблокированы (например, ждут Sleep, select, канал или WaitGroup)

👉 Если одна горутина спит 15 секунд, а другие ничего не делают — synctest просто проматывает время на +15 секунд и продолжает выполнение. Тест проходит мгновенно.

🔄 Что считается «заблокированной» горутиной?
time.Sleep чтение/запись на канале внутри пузыря sync.WaitGroup.Wait, sync.Cond.Wait select, где все ветки — блокирующие

внешние каналы, сетевые операции и другие I/O — не считаются, время не проматывается.

🧪 Что делает synctest.Wait()? Она ждёт, пока все горутины внутри пузыря станут заблокированы — полезно для проверки фоновых задач перед утверждением результата.

#select #синтетическоевремя
Please open Telegram to view this post
VIEW IN TELEGRAM
72👍2🔥2
💪 Go 1.25 Release Candidate 3 уже доступен!

🤓 Анонс: https://groups.google.com/g/golang-announce/c/sTNnwCTjr1Y/m/tdIX-dDUAgAJ

🔨 Скачать: https://go.dev/dl/#go1.25rc3

🤓 В этом релизе исправлены две важные уязвимости:
os/exec.LookPath мог возвращать путь к бинарям, если PATH содержал исполняемые файлы вместо директорий — теперь поведение корректно (CVE‑2025‑47906).
database/sql.Rows.Scan иногда возвращал некорректные значения — баг устранён.

❤️ Версия уже доступна для тестирования и продакшн-сценариев: go.dev/issue/new
Please open Telegram to view this post
VIEW IN TELEGRAM
42🥰1👀11
🤓 Если вы когда‑нибудь писали на JavaScript, то знаете связку async/await: оборачиваем функцию в async, а потом в другом месте делаем await, чтобы дождаться результата.

В Go такого синтаксиса нет… но мы можем им прикинуться. С помощью каналов и горутин получится что‑то похожее.

fn := async(func() any {
return "Hello, JavaScript!"
})

res := await(fn)
fmt.Println(res)
// Hello, JavaScript!
async — принимает функцию, запускает её в отдельной горутине и возвращает канал, по которому придёт результат.

await — просто читает из канала и возвращает то, что туда положили.
func async(f func() any) <-chan any {
out := make(chan any, 1) // буфер, чтобы горутина не блокировалась
go func() {
defer close(out)
out <- f() // выполняем функцию и отправляем результат
}()
return out
}

func await(in <-chan any) any {
return <-in // ждём данные из канала
}
По сути:

async → заворачивает работу в горутину + канал.

await → читает результат из канала, синхронно дожидаясь окончания работы.

🦄 Это, конечно, шуточный приём, и в реальных проектах так лучше не делать — в Go уже есть привычные подходы к конкурентности через goroutine + channel или sync.WaitGroup. Но как способ пошутить над синтаксисом — почему бы и нет.
Please open Telegram to view this post
VIEW IN TELEGRAM
5😁4👍3👨‍💻1
This media is not supported in your browser
VIEW IN TELEGRAM
Когда Go-разработчик получил свою первую зарплату💪
Please open Telegram to view this post
VIEW IN TELEGRAM
😁24🤣11