
- Главная
- Каталог
- Интернет технологии
- Библиотека Go разработчика
Библиотека Go разработчика
Полезные материалы по всему, что может быть полезно разработчику на Go.
Статистика канала
— Пре-анонс security-фиксов в Go
Патчи выйдут 21 мая. Конкретика пока не раскрыта, известны только номера CVE.
— Как закрыть дыру в контейнере
— fsnotify напугала сообщество
— ACME-клиент на Go
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Мы недавно писали про
purego, который позволяет вызывать C-функции из Go без Cgo. speedboost решает ту же задачу, но заходит с другой стороны. Авторы заявляют меньший оверхед на вызов по сравнению с
purego и более низкоуровневый контроль над тем, как именно происходит взаимодействие с shared-библиотекой.Как это работает
API состоит из четырёх шагов. Вы загружаете shared-библиотеку, получаете указатель на символ, описываете сигнатуру функции через дескрипторы типов и вызываете её.
Важная особенность — библиотеку можно встроить прямо в Go-бинарник через
//go:embed. Это значит, что .so / .dylib / .dll файл не нужно таскать отдельно, он будет внутри вашего приложения.Вот пример. Допустим, у нас есть функция
multiply, написанная на Zig и скомпилированная в shared-библиотеку.const std = @import("std");
export fn multiply(a: f64, b: f64) callconv(.c) f64 {
return a * b;
}
Go-код, который её вызывает:
//go:embed lib/zig-out/mymath.shared
var sharedLibrary []byte
func main() {
lib, err := sb.LoadLibrary(sharedLibrary)
if err != nil {
panic(err)
}
defer lib.Unload()
mulPtr := lib.GetSymbol("multiply")
cif := sb.SetFuncSignature(
sb.DoubleTypeDescriptor,
sb.DoubleTypeDescriptor,
sb.DoubleTypeDescriptor,
)
var result float64
err = sb.CallFunction(cif, mulPtr, Ptr(&result),
Ptr(new(40.0)), Ptr(new(2.0)))
fmt.Printf("multiply(40.0, 2.0) = %f\n", result) // 80.0
}
Отличия от purego
В
purego вы объявляете Go-функцию и привязываете её к C-символу через RegisterLibFunc. Это удобный и высокоуровневый подход. В speedboost всё явнее. Вы сами описываете сигнатуру через дескрипторы типов (DoubleTypeDescriptor и т.п.) и передаёте аргументы как unsafe.Pointer. Больше контроля, но больше ручной работы.Авторы
speedboost утверждают, что их подход даёт меньший оверхед на каждый FFI-вызов. Независимых бенчмарков пока нет, поэтому делать выводы о производительности стоит осторожно.Кросс-компиляция
Как и
purego, speedboost работает с CGO_ENABLED=0. Для сборки под другую платформу достаточно указать GOOS.GOOS=linux go generate ./...
GOOS=linux CGO_ENABLED=0 go run .
В примере из репозитория shared-библиотека собирается на Zig, который сам по себе хорош для кросс-компиляции. Но
speedboost не привязан к Zig — подойдёт любая библиотека с C ABI, собранная на C, Rust или чём угодно ещё.Стоит ли использовать
Если вам интересен FFI в Go без Cgo и вы хотите попробовать альтернативу
purego с более низкоуровневым API, speedboost стоит посмотреть. Особенно если в вашем сценарии критичен оверхед на каждый вызов.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Допустим, у вас есть строка байтов:
data := []byte("foo,,bar,,,baz")
Вы хотите разбить её по запятой. Но между элементами — где одна, а где три запятые.
Как это сделать правильно? Ответ смотрите в нашем канале с вопросами с собесов
📍 Навигация: Вакансии • Задачи • Собесы
#ReadySetGo
Если вы когда-нибудь автоматизировали получение TLS-сертификатов через Let's Encrypt или другой ACME-совместимый CA, то наверняка сталкивались с
lego. lego — это ACME-клиент и библиотека на Go, которая поддерживает более 210 DNS-провайдеров и работает на всех основных платформах. Недавно вышел апдейт, давайте глянем что там.Одна команда вместо двух
Главное изменение в CLI: команды
run и renew объединены в одну lego run. Она сама понимает, нужно получить новый сертификат или продлить существующий. Флаги переехали с глобального уровня на уровень команды.Было в v4:
lego --dns cloudflare -d '*.example.com' -d example.com run
Стало в v5:
lego run --dns cloudflare -d '*.example.com' -d example.com
Конфигурационный файл
Теперь можно описать всё в
.lego.yml и не городить длинные команды в кроне или CI. Сертификаты, челленджи, аккаунты, хуки, логирование — всё в одном файле. Есть JSON Schema для валидации:
challenges:
cf:
dns:
provider: cloudflare
certificates:
my-cert:
challenge: cf
domains:
- example.com
- '*.example.com'
После этого достаточно передать креды через переменные окружения (или dotenv) и запустить:
CLOUDFLARE_EMAIL="you@example.com" \
CLOUDFLARE_API_KEY="yourkey" \
lego
Управление аккаунтами, сертификатами и архивами
В v5 появились отдельные подкоманды для работы с данными lego.
Аккаунты:
lego accounts register, lego accounts recover, lego accounts keyrollover, lego accounts list.Сертификаты:
lego certificates list (статус и дата истечения), lego certificates revoke.Архивы:
lego archives list, lego archives restore.Хуки жизненного цикла
Можно повесить скрипты на три этапа выпуска сертификата.
pre-hook срабатывает до получения или продления (только если реально что-то произойдёт). deploy-hook — после успешного выпуска. post-hook — после завершения операции в любом случае.lego run -d 'example.com' --deploy-hook='./my-deploy-hook.sh'
Или через конфиг:
hooks:
pre:
command: './my-pre-hook.sh'
deploy:
command: './my-deploy-hook.sh'
post:
command: './my-post-hook.sh'
Хуки получают контекст через переменные окружения:
LEGO_HOOK_CERT_PATH, LEGO_HOOK_CERT_KEY_PATH и другие.Что ещё нового
Поддержка IPv6-only хостов через флаг
--ipv6only. Структурированное логирование в форматах text, colored и json. Короткие имена CA-серверов вместо полных URL:lego run --server='letsencrypt-staging' ...
lego run --server='zerossl' ...
lego run --server='googletrust' ...
Добавлено 24 новых DNS-провайдера, общее число перевалило за 210. EAB-креденшелы теперь нужны только при первой регистрации аккаунта, а не при каждом продлении.
Миграция с v4
В v5 есть ломающие изменения в CLI, структуре директорий и API библиотеки. Перед использованием нужно выполнить:
lego migrate
Эта команда перенесёт хранилище на новый формат. Полное руководство по миграции есть в документации проекта.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Посмотрим, как применять типовые параметры к структурам. На практике это позволяет создавать переиспользуемые контейнеры и паттерны, знакомые по Rust и другим языкам.
Классический пример. Стек, который работает с любым типом данных:
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(item T) {
s.items = append(s.items, item)
}
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item, true
}
Обратите внимание на паттерн
var zero T. В Go нельзя вернуть nil для произвольного типа, поэтому создаётся нулевое значение через объявление переменной.Использование выглядит так:
intStack := &Stack[int]{}
intStack.Push(1)
intStack.Push(2)
val, _ := intStack.Pop() // 2
Тип указывается явно при создании, дальше компилятор всё отслеживает сам.
Pair
Ещё один частый паттерн. Пара из двух значений разных типов:
type Pair[T, U any] struct {
First T
Second U
}
func NewPair[T, U any](first T, second U) Pair[T, U] {
return Pair[T, U]{First: first, Second: second}
}
Удобно, когда нужно вернуть из функции два связанных значения, не создавая под это отдельную структуру.
Паттерн из Rust. Вместо пары
(value, error) используется единый тип, который содержит либо значение, либо ошибку:type Result[T any] struct {
value T
err error
}
func Ok[T any](value T) Result[T] {
return Result[T]{value: value}
}
func Err[T any](err error) Result[T] {
return Result[T]{err: err}
}
func (r Result[T]) Unwrap() T {
if r.err != nil {
panic(r.err)
}
return r.value
}
func (r Result[T]) UnwrapOr(defaultValue T) T {
if r.err != nil {
return defaultValue
}
return r.value
}
На практике это может выглядеть так:
func divide(a, b float64) Result[float64] {
if b == 0 {
return Err[float64](errors.New("division by zero"))
}
return Ok(a / b)
}
result := divide(10, 2)
fmt.Println(result.Unwrap()) // 5
Стоит ли использовать
Result вместо обычного (T, error)? Для большинства Go проектов привычные множественные возвраты по-прежнему предпочтительнее. Но
Result может быть полезен, если вы строите библиотеку с цепочками вызовов или хотите добавить метод UnwrapOr для значений по умолчанию.Похожий паттерн, но для случая «значение есть или его нет».
В Go это обычно решается через указатели, но
Optional делает намерение явным:type Optional[T any] struct {
value *T
}
func Some[T any](value T) Optional[T] {
return Optional[T]{value: &value}
}
func None[T any]() Optional[T] {
return Optional[T]{value: nil}
}
func (o Optional[T]) UnwrapOr(defaultValue T) T {
if o.value == nil {
return defaultValue
}
return *o.value
}
Как и с
Result, это не замена идиоматичному Go, а дополнительный инструмент для случаев, когда нужна явная семантика «пусто/не пусто».Дженерик-типы позволяют создавать универсальные контейнеры и паттерны без потери типобезопасности.
Стек, пара,
Result, Optional — всё это переиспользуемые строительные блоки, которые раньше приходилось реализовывать через interface{}.📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
У популярной Go-библиотеки
fsnotify сменились доступы к репозиторию, и open source-сообщество забеспокоилось. Библиотеку используют более 321 000 проектов на GitHub, она лежит в основе множества CLI-инструментов, dev-серверов и инфраструктурных пайплайнов. Когда непонятно, кто именно может пушить код в такую зависимость, последствия чувствуют все.
Go-разработчик Yasuhiro Matsumoto (mattn) написал в X, что его удалили из GitHub-организации
fsnotify без объяснений. Пост был на японском, позже его удалили, но к тому моменту сообщество уже забило тревогу. Выглядело это как классический набор признаков supply chain компрометации: изменение доступов, свежие релизы, удалённый публичный.
Мейнтейнер проекта Martin Tournoij ответил в GitHub-тикете. По его словам, удалённые аккаунты имели коммит-права по историческим причинам, но никогда не были полноценными мейнтейнерами.
Он объяснил, что изменения мержились слишком быстро, без должного ревью на всех поддерживаемых платформах. Ещё одной причиной стало то, что Matsumoto закоммитил напрямую в main без обсуждения. Matsumoto позже признал это ошибкой и извинился.
Реакция экосистемы
Ситуация быстро дошла до крупных проектов. В Kubernetes завели отдельный тикет с вопросом о здоровье
fsnotify и предложением рассмотреть форки. Инженер Docker Sebastiaan van Stijn отметил, что такие библиотеки сидят настолько глубоко в стеке, что о них забывают, а инструменты вроде Dependabot обновляют зависимости почти без контроля.
Аналитики Socket.dev подчеркнули важный момент: на ранних стадиях supply chain атака и обычный конфликт мейнтейнеров выглядят одинаково.
Смена доступов, неожиданные релизы, противоречивые публичные заявления. История с бэкдором в
xz-utils всё ещё свежа в памяти, поэтому реакция сообщества была предсказуемо резкой.Вредоносного кода в
fsnotify не обнаружено. Но сама ситуация показательна. Если вы используете эту библиотеку, стоит проверить историю релизов и следить за развитием событий.Мониторинг активности мейнтейнеров в критичных зависимостях, проверка release history при любых спорных ситуациях и готовность переключиться на форк — это то, что сейчас рекомендуют делать всем.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
gorilla/mux годами был стандартным выбором для HTTP-роутинга в Go. Он добавлял параметры пути, роутинг по методам и поддержку middleware поверх скромного ServeMux. Но Go 1.22 закрыл большинство этих пробелов.Что изменилось в Go 1.22
Стандартный
ServeMux теперь поддерживает методы и параметры пути прямо в паттерне маршрута:mux := http.NewServeMux()
mux.HandleFunc("GET /deposits/{walletID}", handleGetDeposit)
mux.HandleFunc("POST /deposits", handleCreateDeposit)
mux.HandleFunc("DELETE /deposits/{walletID}", handleDeleteDeposit)
Параметр пути читается через
r.PathValue("walletID"). Роутинг по методу встроен. Для большинства REST API, внутренних сервисов и обработчиков вебхуков этого достаточно.Когда нужна внешняя библиотека
Если реально нужны сложные цепочки middleware, субрутеры или маршруты с регулярными выражениями — возьмите
github.com/go-chi/chi/v5. Он легче Gorilla, хорошо компонуется и следует идиомам Go.Почему не Gorilla
Gorilla Mux поддерживается, но его дни как разумного дефолта прошли. Вы добавляете зависимость ради функций, которые теперь есть в стандартной библиотеке.
Для нового проекта на Go 1.22+: начните с
net/http. Если не хватает — возьмите chi. Gorilla Mux нужен только в очень специфических случаях или при поддержке старого кода.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Если вы работали с Go и вам нужно было вызвать C-библиотеку, то вы наверняка сталкивались с Cgo.
Cgo работает, но тянет за собой целый набор проблем. Нужен C-компилятор на каждой целевой платформе. Кросс-компиляция превращается в боль. Сборка замедляется. Бинарники раздуваются.
purego решает всё это, позволяя вызывать C-функции из чистого Go.Откуда взялся проект
Библиотека выросла из игрового движка Ebitengine. Его авторы портировали движок на чистый Go для Windows, что позволило кросс-компилировать на Windows с любой ОС одной командой
GOOS=windows. purego родился, чтобы принести тот же подход на macOS, Linux и другие платформы.Что даёт purego
Без Cgo отпадает необходимость в C-компиляторе. Вы можете собирать проект под другую платформу, просто задав
GOOS и GOARCH. Сборка кешируется целиком как обычный Go-проект и работает быстрее. Бинарники становятся меньше, потому что Cgo генерирует обёртку на C для каждого вызова, а purego этого не делает.Ещё
purego умеет загружать символы из shared-библиотек в рантайме. Это можно использовать как систему плагинов или для FFI-вызовов в библиотеки на других языках, скомпилированные в .so / .dylib / .dll.purego работает и при CGO_ENABLED=1. Это значит, что можно портировать проект с Cgo на purego постепенно, не переписывая всё разом.Как это выглядит в коде
API минимальный. Вы открываете библиотеку через
Dlopen, затем регистрируете Go-функцию, которая будет вызывать C:package main
import (
"fmt"
"runtime"
"github.com/ebitengine/purego"
)
func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}
func main() {
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
puts("Calling C from Go without Cgo!")
}
Обратите внимание на
RegisterLibFunc. Вы объявляете переменную с нужной Go-сигнатурой, а purego привязывает её к C-функции по имени. Никаких // #cgo директив, никаких .h файлов.Когда стоит использовать
purego подходит, если вам нужно вызывать C-библиотеку из Go и при этом важна простота сборки и кросс-компиляция. Типичные сценарии — работа с системными библиотеками, графические движки, аудио, нативные SDK.Если ваш проект уже плотно завязан на Cgo и работает на одной платформе, смысла переезжать может не быть. Но если вы начинаете новый проект или хотите избавиться от зависимости на C-тулчейн,
purego стоит попробовать.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
👨💻 Урок проведёт руководитель курса «Go-разработчик. Продвинутый уровень» Юра Рубаха. На вебинаре сможете задать любые вопросы по программе, чтобы убедиться, что курс вам подходит.
Урок проходит в преддверии старта курса «Go-разработчик. Продвинутый уровень». Если вы хотите писать предсказуемые и эффективные сервисы — подключайтесь.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Отзывы канала
всего 4 отзыва
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
Библиотека Go разработчика — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 24.0K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 9.5, количество отзывов – 4, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 30349.62 ₽, а за 19 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий