TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7367 3.35K
🧑‍💻 Билдеры, которые не ломаются при встраивании

Продолжаем разбирать [T Constraint[T]] в объявлениях обобщённых типов. Это чинит старую проблему флюентных билдеров, где цепочку вызовов ломало встраивание.

Какую боль это решает

У билдера в Go давнее противоречие. Чтобы работала цепочка .WithX().WithY().Build(), каждый метод возвращает *Builder. Пока билдер один, всё в порядке. Но как только вы расширяете его через встраивание, цепочка рвётся. Метод встроенного типа возвращает встроенный тип, а не внешний, поэтому после первого же вызова вы теряете доступ к методам расширения. Приходится либо дублировать методы, либо приводить типы вручную.

Как это работает

Ограничение задаёт набор методов, а параметр типа B несёт конкретный тип билдера через всю цепочку:
type Builder[B any] interface {
WithTimeout(d time.Duration) B
WithRetry(attempts int, backoff time.Duration) B
Build() (Config, error)
}

// ApplyDefaults возвращает B, а не Builder[B].
func ApplyDefaults[B Builder[B]](b B, env Environment) B {
b = b.WithTimeout(env.DefaultTimeout())
b = b.WithRetry(env.MaxRetries(), env.RetryBackoff())
return b
}


На вызове конкретный тип остаётся живым, поэтому специфичный метод вроде WithHeader доступен прямо в цепочке:
client, err := ApplyDefaults(NewHTTPClientBuilder("https://api.internal"), prodEnv).
WithHeader("X-Service-ID", serviceID). // всё ещё доступно
Build()


Здесь важно разделение двух задач. Интерфейс задаёт ограничение, какие методы обязаны быть. Параметр типа несёт идентичность, какой именно конкретный билдер вернётся. Передача обеих задач одной переменной типа как раз и заставляет паттерн работать.

Самоссылка снимает старый компромисс между цепочкой вызовов и расширением билдера. Общие настройки выносятся в одну обобщённую функцию, а конкретный тип переживает всю цепочку, поэтому доменные методы остаются под рукой без приведений. Для конфигураторов, клиентов и любых флюентных API это делает код короче и безопаснее на этапе компиляции.

📍 Навигация: Вакансии • Задачи • Собесы

🐸 Библиотека Go-разработчика

#GoToProduction
  • 👍 5
  • ❤ 2
More from @goproglib
  1. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
  2. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
  3. Sep 23, 2026💥 TCP/IP: что происходит с данными в сети Когда Go-приложение отправляет данные по сети,…
  4. Sep 22, 2026🔴 Встроенные функции len, make, panic — встроенные функции Go, которые можно использовать…
  5. Sep 21, 2026🤩 Go с нуля: серия базовых шпаргалок Собрали путь от Hello, World! до goroutines, channel…
  6. Sep 20, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — [1 2 3 4 5] / [1 2 10] 🔥 — [1…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →