Представим, что дженерики пропали из языка. Тогда мы столкнемся с дублированием кода. Придется описывать один и тот же алгоритм для разных типов данных много раз.
Возьмем для примера функцию last()
, возвращающую последний элемент массива. Ниже ее обобщенная версия:
function last<T>(coll: T[]): T {
return coll.at(-1);
}
Теперь попробуем реализовать такое же поведение на обычных функциях. Для этого нам придется создать по одной функции для каждого типа. Причем имя функции должно быть уникальным:
function lastForNumberType(coll: number[]): number {
return coll.at(-1);
}
function lastForStringType(coll: string[]): string {
return coll.at(-1);
}
// Тут определения для всех остальных типов
А что если у нас несколько типов? Тогда нужно подсчитать, сколько функций нужно определить — умножить количество всех возможных типов на количество параметров типа.
Реализация с помощью перегруженной функции упрощает задачу. При работе с ними нам не придется создавать новые имена:
function last(coll: number[]): number;
function last(coll: string[]): string;
// Тут определения для всех остальных типов
function last(coll: any[]): any {
return coll.at(-1);
}
В случае TypeScript даже логика не будет дублироваться, но это особенность именно TypeScript. В других статически типизированных языках придется дублировать и логику тоже.
Какой бы вариант реализации мы ни выбрали, соблюдаются две вещи:
- Передаваемые внутрь значения никак не используются, они только перекладываются из одного места в другое
- Логика работы всегда остается одной и той же, условные конструкции по типу данных отсутствуют
В Computer Science есть один важный термин — параметрический полиморфизм. Это свойство функции, позволяющее обрабатывать значения разных типов одним способом, используя один алгоритм. Это значит, что дженерики — это реализация параметрического полиморфизма в TypeScript.
Параметрический полиморфизм играет важную роль в статически типизированных языках, потому что там приходится явно указывать типы у функций. Он есть почти во всех высокоуровневых статически типизированных языках. В Java и C# это тоже называется дженериками. В C++ используется термин «шаблоны», но смысл от этого не меняется, хотя шаблоны в С++ — это больше, чем параметрический полиморфизм.
В противовес статически типизированным языкам есть JavaScript, Python, Ruby, PHP и другие языки с динамической типизацией. В них дженерики не нужны. В подобных языках любой обобщенный алгоритм автоматически работает для всех типов данных.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.