
- Главная
- Каталог
- Интернет технологии
- Библиотека Go разработчика
Библиотека Go разработчика
Полезные материалы по всему, что может быть полезно разработчику на Go.
Статистика канала
Senior Golang Developer — офис в Сербии
Senior Golang-разработчик — от 300 000 ₽, удаленно по Москве
Golang-разработчик — до 150 000 ₽, удаленно или гибрид в Москве
#GoWork
Команда GigaChat зовёт на One Day Offer амбициозных Java-разработчиков, которые готовы создавать AI‑продукты уровня BigTech и стать частью крупнейшего AI-комьюнити.
Если ты дружишь с Java (версии 8–25), ладишь со Spring и Hibernate, а PostgreSQL и ClickHouse для тебя — не просто слова, переходи по ссылке и занимай слот на One Day Offer.
Встречаемся 23 мая — очень ждём именно тебя!
Разберём тип
Duration, операции сложения и вычитания дат, сравнение и работу с часовыми поясами.Duration
time.Duration — это промежуток времени в наносекундах. Создаётся через умножение на константы пакета:d := 5 * time.Second
d := 2*time.Hour + 30*time.Minute
d := time.Duration(500) * time.Millisecond
Можно распарсить из строки:
d, err := time.ParseDuration("1h30m")
d, err := time.ParseDuration("2h45m30s")
d, err := time.ParseDuration("100ms")
d, err := time.ParseDuration("-1h") // отрицательная длительность
У
Duration есть методы для конвертации в нужные единицы:d := 2*time.Hour + 30*time.Minute + 45*time.Second
d.Hours() // 2.5125
d.Minutes() // 150.75
d.Seconds() // 9045
d.Milliseconds() // 9045000
d.String() // 2h30m45s
Доступные константы:
time.Nanosecond // 1
time.Microsecond // 1000 наносекунд
time.Millisecond // 1000 микросекунд
time.Second // 1000 миллисекунд
time.Minute // 60 секунд
time.Hour // 60 минут
Арифметика времени
Добавить
Duration к time.Time:now := time.Now()
future := now.Add(24 * time.Hour)
future := now.Add(2*time.Hour + 30*time.Minute)
Для календарных операций (где важны границы месяцев и лет) есть
AddDate():nextMonth := now.AddDate(0, 1, 0) // +1 месяц
nextYear := now.AddDate(1, 0, 0) // +1 год
lastWeek := now.AddDate(0, 0, -7) // -7 дней
Разница между двумя моментами:
diff := future.Sub(now) // возвращает Duration
fmt.Println(diff.Hours())
Два удобных сокращения:
elapsed := time.Since(start) // то же, что time.Now().Sub(start)
remaining := time.Until(deadline) // то же, что deadline.Sub(time.Now())
Сравнение
Методы
Before(), After() и Equal() делают то, что ожидаешь:t1 := time.Now()
t2 := t1.Add(time.Hour)
t1.Before(t2) // true
t1.After(t2) // false
t1.Equal(t2) // false
Начиная с Go 1.20 появился метод
Compare(), который возвращает -1, 0 или 1:cmp := t1.Compare(t2) // -1 (t1 раньше t2)
Таймзоны
Загрузка таймзоны по имени IANA:
nyc, err := time.LoadLocation("America/New_York")
tokyo, err := time.LoadLocation("Asia/Tokyo")
utc := time.UTC
local := time.Local
Конвертация между зонами:
now := time.Now()
utcTime := now.UTC()
nycTime := now.In(nyc)
Создание времени сразу в нужной зоне:
t := time.Date(2024, 1, 15, 10, 30, 0, 0, nyc)
Получить информацию о текущей зоне:
name, offset := now.Zone()
fmt.Println(name, offset) // EST -18000 (смещение в секундах)
Если нужна зона с фиксированным смещением:
est := time.FixedZone("EST", -5*60*60)
Важный момент:
time.LoadLocation() ищет данные IANA в системе. Если на сервере нет файла tzdata, вызов вернёт ошибку. В Go 1.15 появился пакет time/tzdata, который вшивает базу зон прямо в бинарник. Достаточно импорта:import _ "time/tzdata"
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Это vibe hiring — найм по ощущению, где решение принимается до того, как рекрутер посмотрел на ваши компетенции.
В статье — данные двух крупных исследований 2025–2026 годов, гендерная статистика по фидбеку с интервью и объяснение, почему субъективный найм бьёт по самой компании сильнее, чем по кандидату.
📍 Навигация: Вакансии • Задачи • Собесы
21 мая(в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_go_bot Реклама.
О рекламодателе.
Разберём базу: как получить текущее время, как создать конкретную дату и как форматировать и парсить строки. Всё на примерах из стандартной библиотеки, без сторонних зависимостей.
Текущее время и его компоненты
Всё начинается с
time.Now(). Этот вызов возвращает структуру time.Time с текущим временем:now := time.Now()
fmt.Println(now) // 2024-01-15 10:30:00.123456789 -0500 EST
Из неё можно вытащить любой компонент через методы:
now.Year() // 2024
now.Month() // January
now.Day() // 15
now.Hour() // 10
now.Minute() // 30
now.Second() // 0
now.Weekday() // Monday
now.YearDay() // 15 (день в году)
Для интеграций часто нужны Unix-таймстемпы:
now.Unix() // 1705329000 (секунды)
now.UnixMilli() // 1705329000123 (миллисекунды)
now.UnixNano() // 1705329000123456789 (наносекунды)
Создание конкретной даты
Если нужно задать дату руками, используйте
time.Date():t := time.Date(2024, time.January, 15, 10, 30, 0, 0, time.UTC)
Аргументы по порядку: год, месяц, день, час, минута, секунда, наносекунда, таймзона.
Из Unix-таймстемпа:
t := time.Unix(1705329000, 0)
t := time.UnixMilli(1705329000123)
Из строки через парсинг:
t, err := time.Parse("2006-01-02", "2024-01-15")
t, err := time.Parse(time.RFC3339, "2024-01-15T10:30:00Z")
Нулевое значение
time.Time можно проверить методом IsZero():var t time.Time
fmt.Println(t.IsZero()) // true
Форматирование и парсинг
Тут Go отличается от большинства языков. Вместо
%Y-%m-%d или yyyy-MM-dd используется референсная дата: Mon Jan 2 15:04:05 MST 2006. Запоминается просто: 1/2 3:4:5 2006.Форматируем в строку:
now.Format("2006-01-02") // 2024-01-15
now.Format("02/01/2006") // 15/01/2024
now.Format("January 2, 2006") // January 15, 2024
now.Format("15:04:05") // 10:30:00
now.Format("3:04 PM") // 10:30 AM
Есть готовые константы:
now.Format(time.RFC3339) // 2024-01-15T10:30:00-05:00
now.Format(time.Kitchen) // 10:30AM
now.Format(time.DateOnly) // 2024-01-15 (Go 1.20+)
now.Format(time.TimeOnly) // 10:30:00 (Go 1.20+)
Парсинг работает зеркально: передаёте тот же шаблон и строку:
t, err := time.Parse("2006-01-02", "2024-01-15")
t, err := time.Parse("01/02/2006 3:04 PM", "01/15/2024 10:30 AM")
Если нужно парсить с привязкой к таймзоне, используйте
time.ParseInLocation():loc, _ := time.LoadLocation("America/New_York")
t, err := time.ParseInLocation("2006-01-02 15:04", "2024-01-15 10:30", loc)
Шпаргалка по символам формата
2006 — 4-значный год06 — 2-значный год01 — месяц с нулём (01)1 — месяц без нуля (1)January — полное название месяцаJan — сокращённое название02 — день с нулём2 — день без нуляMonday — полное название дня неделиMon — сокращённое15 — час в 24-часовом формате03 — час в 12-часовом с нулём3 — час в 12-часовом без нуля04 — минуты05 — секундыPM — AM/PMMST — сокращение таймзоны-07:00 — смещениеZ07:00 — Z для UTC, смещение для остальных📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
В зависимостях Go проекта могут быть известные уязвимости. Можно узнать об этом из новостей, а можно проверять автоматически.
govulncheck — официальный инструмент от команды Go, который находит уязвимости в коде и зависимостях вашего проекта.Чем полезен
Обычные сканеры зависимостей работают грубо. Они сверяют список пакетов с базой CVE и сообщают обо всём, что нашли. Даже если уязвимая функция в вашем коде вообще не вызывается.
govulncheck использует статический анализ и проверяет, какие функции действительно достижимы из вашего кода. Это значит меньше ложных срабатываний и меньше шума в отчётах.Данные об уязвимостях берутся из официальной базы Go. При запросе к базе отправляются только пути модулей, без вашего кода или других данных проекта.
Как использовать
Самый простой сценарий. Переходим в директорию модуля и сканируем все пакеты.
cd my-module
govulncheck ./...
Если уязвимостей нет,
govulncheck выведет короткое сообщение. Если есть, покажет описание каждой уязвимости и краткий call stack, чтобы было понятно, как именно ваш код вызывает уязвимую функцию.Вывод может выглядеть так:
main.go:42:3: mypackage.main calls golang.org/x/text/language.Parse
Чтобы увидеть полный стек вызовов, добавьте флаг:
govulncheck -show traces ./...
Для подробного вывода с прогрессом:
govulncheck -show verbose ./...
Сканирование бинарных файлов
govulncheck умеет проверять не только исходный код, но и скомпилированные бинарники. Для этого используется флаг -mode binary:govulncheck -mode binary $HOME/go/bin/my-go-program
В этом режиме инструмент анализирует таблицу символов бинарника. Call stack при этом не показывается, потому что для него нужен исходный код.
Есть ещё режим
-mode extract. Он извлекает из бинарника минимальную информацию, нужную для анализа, и сохраняет её в отдельный файл. Этот файл обычно гораздо меньше оригинального бинарника, и его тоже можно передать в govulncheck с флагом -mode binary.Форматы вывода
Помимо текстового вывода,
govulncheck поддерживает несколько машиночитаемых форматов. JSON для потоковой обработки, SARIF для интеграции с CI/CD и инструментами анализа, VEX (Vulnerability EXchange) по спецификации OpenVEX.Что стоит учитывать
Инструмент анализирует вызовы через указатели на функции и интерфейсы консервативно. Это иногда приводит к ложным срабатываниям. Вызовы через пакет
reflect статическому анализу не видны, поэтому уязвимости, достижимые только через рефлексию, в отчёт не попадут. То же касается unsafe.На момент версии v1.1.4 нет встроенного механизма подавления конкретных находок. Задача на это ведётся в https://go.dev/issue/61211.
govulncheck полезен тем, что даёт конкретику. Вместо списка «у вас есть пакет с CVE» он показывает, вызывается ли уязвимая функция в вашем коде. Встраивается в CI, понимает бинарники, выводит в SARIF и JSON. Официальный инструмент, поддерживается командой Go.Знаете где нет уязвимостей?
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Работа с базой данных в Go часто превращается в рутину. Мы пишем SQL-запрос, потом вручную описываем структуру, потом руками сканируем строки в эту структуру. Любая опечатка в имени колонки или несовпадение типов всплывёт только в рантайме.
sqlc подходит к этому иначе. Вы пишете обычный SQL, а sqlc генерирует из него Go-код с типобезопасными интерфейсами. Никаких тегов, никакой рефлексии, никакого рантайм-парсинга. Ошибки ловятся на этапе компиляции.Как это работает
Принцип простой. Вы описываете схему базы, пишете SQL-запросы с аннотациями, запускаете
sqlc generate. На выходе получаете Go-пакет с готовыми функциями, структурами и интерфейсами.Для начала нужен конфиг
sqlc.yaml:version: "2"
sql:
- engine: "postgresql"
queries: "query.sql"
schema: "schema.sql"
gen:
go:
package: "db"
out: "db"
sql_package: "pgx/v5"
Дальше описываем схему в
schema.sql:CREATE TABLE authors (
id BIGSERIAL PRIMARY KEY,
name text NOT NULL,
bio text
);
И пишем запросы в
query.sql. Каждый запрос получает имя и тип результата через аннотацию:-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;
-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;
-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
) RETURNING *;
-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1;
Аннотация
:one означает, что запрос вернёт одну строку. :many — слайс. :exec — ничего не возвращает. Есть ещё :execresult для случаев, когда нужен sql.Result.После запуска
sqlc generate в папке db/ появятся три файла: models.go со структурами, db.go с интерфейсом подключения, query.sql.go с типобезопасными функциями для каждого запроса.Использование в коде выглядит так:
queries := db.New(conn)
author, err := queries.CreateAuthor(ctx, db.CreateAuthorParams{
Name: "Brian Kernighan",
Bio: pgtype.Text{String: "Author of The C Programming Language", Valid: true},
})
authors, err := queries.ListAuthors(ctx)
Никаких строковых имён колонок. Если вы переименуете поле в схеме и забудете обновить запрос,
sqlc generate упадёт с ошибкой. Если типы не совпадут — тоже.Что поддерживается
sqlc работает с PostgreSQL, MySQL и SQLite. Генерация кода доступна для Go, Python, Kotlin и TypeScript. Для Go есть поддержка database/sql, pgx/v4 и pgx/v5. Дополнительные языки подключаются через плагины.Зачем это нужно
sqlc убирает ручной маппинг между SQL и кодом. Вы полностью контролируете свои запросы, при этом получаете строгую типизацию на этапе компиляции. Сгенерированный код читаемый — это обычный Go, который вы бы написали сами, только без ошибок при сканировании строк.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Стандартный
time.Sleep() в Go ничего не знает про контекст. Если вы поставили паузу на 30 секунд, а контекст отменился через 2 — функция всё равно будет ждать все 30. Это проблема в любом коде, где важна отзывчивость на отмену: фоновые воркеры, периодические задачи, graceful shutdown.Решение — написать свою функцию
Sleep, которая завершится досрочно, если контекст будет отменён.Реализация
Создаём таймер и ждём, что произойдёт раньше: таймер сработает или контекст отменится:
func Sleep(ctx context.Context, d time.Duration) {
timer := time.NewTimer(d)
defer timer.Stop()
select {
case <-ctx.Done():
return
case <-timer.C:
return
}
}
select блокирует горутину до тех пор, пока один из каналов не станет готов. Если контекст отменяется раньше таймера — выходим сразу. Если таймер срабатывает первым — выходим как обычный Sleep. В обоих случаях defer timer.Stop() корректно освобождает ресурсы.Пример использования
Допустим, есть фоновая задача, которая выполняется в цикле с паузой между итерациями:
func Job(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
doWork()
Sleep(ctx, 10 * time.Second)
}
}
}
Когда контекст отменится,
Sleep завершится мгновенно. На следующей итерации цикл проверит ctx.Done() и выйдет. Без нашей функции воркер бы завис в time.Sleep на оставшееся время, а сервис не мог бы корректно остановиться.Почему функция не возвращает ошибку
Первый вариант напрашивается сам собой — вернуть
ctx.Err() при отмене контекста:func Sleep(ctx context.Context, d time.Duration) error {
timer := time.NewTimer(d)
defer timer.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
return nil
}
}
Но на практике это усложняет вызывающий код без пользы. Отмена контекста — это не ошибка самого
Sleep. Это сигнал для всей цепочки выполнения. Код после
Sleep обычно тоже проверяет контекст, и если он отменён — тоже завершается. Обрабатывать ошибку именно от Sleep нет смысла, поэтому сигнатура без error делает функцию проще в использовании.Когда это пригодится
Функция полезна везде, где
time.Sleep стоит внутри цикла или последовательности операций, привязанных к контексту. Фоновые джобы, ретраи с задержкой, периодические опросы, rate limiting — всё это становится отзывчивее к отмене без лишнего кода.📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Отзывы канала
всего 4 отзыва
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
Библиотека Go разработчика — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 24.0K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 9.5, количество отзывов – 4, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 13986.0 ₽, а за 19 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий