Вопрос с собеседования · Go

Как устроены дженерики в Go и когда их использовать?

MiddleМетоды и интерфейсыGo >=1.21
Ещё спрашивают так:
  • Что такое ограничения типов (constraints) в Go?
Коротко

С Go 1.18 функции и типы принимают параметры типов с ограничениями — интерфейсами, которые могут перечислять допустимые типы: func Max[T cmp.Ordered](a, b T) T. Применение — контейнеры и алгоритмы над разными типами (пакеты slices, maps). Для поведения по-прежнему лучше обычные интерфейсы.

  • ~int в ограничении — любой тип с базовым int
  • comparable — типы, поддерживающие ==
  • Методы не могут иметь собственных параметров типов

А ещё Не заменять дженериками интерфейсы там, где нужна динамическая диспетчеризация

Подробно

До дженериков обобщённый код писали через interface{} с приведениями типов (теряли проверку на компиляции) или генерацией кода.

Ограничения — интерфейсы, которые описывают либо методы, либо набор типов (int | float64), либо и то и другое. Тильда ~int включает именованные типы с базовым int (type Celsius int). Готовые ограничения: any, comparable, cmp.Ordered.

Стандартная библиотека после 1.21: slices.Sort, slices.Contains, maps.Keys, min/max встроены.

Когда не стоит: если функции нужно лишь вызывать методы аргумента — обычный интерфейс проще. Дженерики хороши для структур данных (стек, кэш, множество) и функций над срезами и мапами.

Пример

func Map[T, U any](xs []T, f func(T) U) []U {
    out := make([]U, 0, len(xs))
    for _, x := range xs { out = append(out, f(x)) }
    return out
}

type Number interface{ ~int | ~int64 | ~float64 }
func Sum[T Number](xs []T) T {
    var s T
    for _, x := range xs { s += x }
    return s
}

type Stack[T any] struct{ items []T }
func (s *Stack[T]) Push(x T) { s.items = append(s.items, x) }

Что хотят услышать

  • Параметры типов и ограничения.
  • Где применять, а где лучше интерфейсы.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Дженерики появились в Go 1.10
  • ✓Параметры типов с ограничениями — для контейнеров и алгоритмов
  • ✗comparable — ограничение для типов, поддерживающих сортировку и операторы < и >
  • ✗Дженерики заменяют интерфейсы для описания поведения

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования