Ответ
Дженерики (обобщённое программирование) — это возможность писать функции и структуры данных, которые могут работать с любым типом, удовлетворяющим определённым условиям. Эта возможность появилась в Go версии 1.18.
Основная цель дженериков — избежать дублирования кода для разных типов данных, сохраняя при этом строгую типизацию.
Ключевые концепции:
- Параметры типа (Type Parameters): Объявляются в квадратных скобках после имени функции.
[T any]
означает, чтоT
— это параметр типа, который может быть любым типом. - Ограничения типа (Type Constraints): Интерфейсы, которые определяют, какие операции разрешены для параметра типа. Например, встроенное ограничение
comparable
позволяет использовать операторы==
и!=
.
Классический пример — функция для суммирования чисел:
Раньше пришлось бы писать две функции: SumInts
и SumFloats
. С дженериками можно написать одну.
// Определяем ограничение, которое разрешает использовать int или float64
type Number interface {
int | int64 | float32 | float64
}
// SumNumbers работает с любым типом, подходящим под ограничение Number
func SumNumbers[T Number](a, b T) T {
return a + b
}
func main() {
// Использование с int
sumInt := SumNumbers(5, 10) // Результат: 15
fmt.Println(sumInt)
// Использование с float64
sumFloat := SumNumbers(3.14, 2.71) // Результат: 5.85
fmt.Println(sumFloat)
}
Преимущества:
- Переиспользование кода: Одна функция для множества типов.
- Типобезопасность: Компилятор проверяет типы во время компиляции, в отличие от использования
interface{}
с приведением типов. - Читаемость: Код становится более лаконичным и выразительным.
Когда использовать:
- При работе с коллекциями: слайсами, картами, каналами.
- При написании общих алгоритмов: сортировка, поиск, фильтрация.
- В структурах данных, таких как деревья, списки, графы.