TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7370 2.75K
⭐️ Самоупорядочивающиеся типы в Go для доменных значений

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

Стандартный constraints.Ordered покрывает числа и строки, но не богатые доменные типы вроде Priority, SemanticVersion или Money. Для них порядок задаётся своей логикой, а не оператором <. Обычно это решают через sort.Slice с замыканием на каждый вызов или через хранение значений как interface{} с приведением при каждом сравнении. Первый вариант рассыпает логику сравнения по коду, второй теряет типобезопасность и добавляет работу рантайму.

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

Ограничение требует, чтобы тип умел сравнивать себя с себе подобным:
type Ordered[T any] interface {
Less(other T) bool
}

// T обязан реализовать Less(T) bool.
type SortedSlice[T Ordered[T]] struct {
items []T
}

func (s *SortedSlice[T]) Insert(v T) {
i := sort.Search(len(s.items), func(i int) bool {
return !s.items[i].Less(v)
})
s.items = append(s.items, v)
copy(s.items[i+1:], s.items[i:])
s.items[i] = v
}


Доменный тип реализует Less для себя:
type Priority int

func (p Priority) Less(other Priority) bool {
return p < other
}

set := &SortedSlice[Priority]{}
set.Insert(High)
set.Insert(Low)


SortedSlice[Priority]
на этапе компиляции знает, что хранит именно Priority. Вызов .Less прямой, без интерфейсной прослойки в рантайме. Если попытаться вставить тип, который не реализует Ordered[T] для себя, компилятор отклонит его прямо на месте вызова, а не оставит падать под нагрузкой.

Паттерн переносит правило сравнения внутрь самого типа и даёт коллекцию, которая держит порядок для любого доменного значения. Логика Less живёт в одном месте, типобезопасность сохраняется, приведений нет. Для приоритетных очередей, версий и денежных сумм это чище, чем замыкания на каждый вызов сортировки.

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

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

#GoToProduction
  • ❤ 8
  • 👍 4
  • 🔥 2
More from @goproglib
  1. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
  2. Sep 23, 2026💥 TCP/IP: что происходит с данными в сети Когда Go-приложение отправляет данные по сети,…
  3. Sep 22, 2026🔴 Встроенные функции len, make, panic — встроенные функции Go, которые можно использовать…
  4. Sep 21, 2026🤩 Go с нуля: серия базовых шпаргалок Собрали путь от Hello, World! до goroutines, channel…
  5. Sep 20, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — [1 2 3 4 5] / [1 2 10] 🔥 — [1…
  6. Sep 19, 2026🛠 Rune — open-source IDE и terminal multiplexer на Go Rune объединяет IDE, терминал и AI-…
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 →