Go: Дженерики
Теория: Универсальные функции
Обычная функция в Go работает с заранее заданным типом. Универсальная функция использует параметр типа и применяет одну и ту же логику к разным данным. Такой параметр указывается в квадратных скобках после имени функции и затем участвует в сигнатуре.
Функция может обобщаться как по одному типу, так и по нескольким сразу. Когда нужен только один параметр, он объявляется в квадратных скобках и используется в сигнатуре вместо конкретного типа:
Здесь параметр T связывает аргумент и возвращаемое значение: тип входа и выхода будет одним и тем же. Если же требуется больше гибкости, можно ввести несколько параметров. Они указываются через запятую в скобках. Например, функция, создающая пару из двух значений разных типов:
Параметры типа можно использовать в любых частях сигнатуры: среди аргументов, в возвращаемых значениях, внутри структур и методов. Они играют ту же роль, что и обычные типы, только определяются не заранее, а в момент вызова функции. Если функция принимает срез []T, то она обязана вернуть результат того же типа T, что был подставлен при вызове. Это гарантирует согласованность и строгую проверку типов.
Пример функции поиска минимального элемента показывает, как параметр типа можно ограничить операциями сравнения. Для этого используют constraints.Ordered:
Здесь T подходит для чисел и строк. Вызов Min(3, 7) вернёт 3, а Min("go", "java") — строку "go".
Другой пример — поиск значения в срезе. Здесь параметр T участвует и в типе элементов, и в типе искомого значения:
Такое описание не позволит искать строку в срезе чисел — строгая типизация сохраняется.
Функция реверса показывает, что параметр типа может использоваться только для элементов, а логика при этом остаётся общей:
Она одинаково работает для []int, []string и любых других срезов.
Параметры типа делают возможным написание лаконичных и универсальных функций. Они позволяют описывать общую логику один раз и применять её к разным данным, сохраняя строгую проверку на этапе компиляции.



