Ответ
Generics (обобщения), появившиеся в Go 1.18, — это механизм, который позволяет писать функции и типы данных, способные работать с любым из набора типов, не дублируя код. Основная цель — повышение переиспользуемости кода и обеспечение строгой типизации.
Ключевые концепции:
- Параметры типа (Type Parameters): Объявляются в квадратных скобках
[T any]
.T
— это имя параметра типа, аany
— его ограничение (constraint). - Ограничения (Constraints): Это интерфейсы, которые определяют, какие типы могут быть использованы в качестве аргумента типа.
any
— это псевдоним дляinterface{}
, разрешающий любой тип.
Пример: Обобщенная функция
Эта функция может напечатать слайс любого типа:
// T - параметр типа, any - ограничение (любой тип)
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
func main() {
PrintSlice([]int{1, 2, 3})
PrintSlice([]string{"a", "b", "c"})
}
Пример с ограничением:
Можно создать ограничение, чтобы функция работала только с типами, поддерживающими определенные операции. Например, для суммирования чисел:
// Определяем интерфейс-ограничение
// (в стандартной библиотеке есть constraints.Ordered)
type Number interface {
int | int64 | float32 | float64
}
// Функция работает только с типами, удовлетворяющими Number
func Sum[T Number](numbers []T) T {
var total T
for _, n := range numbers {
total += n
}
return total
}
Преимущества:
- Код без дублирования (DRY): Одна функция для разных типов.
- Типобезопасность: Компилятор проверяет типы во время компиляции, в отличие от
interface{}
.