- наш обучающий телеграм канал для Golang разработчиков
- папка с самыми полезными ресурсами для Golang разработчиков
Go статически типизированный язык. Это значит, что типы переменных проверяются на этапе компиляции. Встроенные типы в Go, такие как мапы, слайсы каналы, а также встроенные функции, например len и make умеют работать с разными типами. Но до версии пользовательские типы так не умели.
Это значит, что в Go, если я реализую бинарное дерево для, например, типа int:
и потом понадобится реализовать дерево для strings или float, и мне будет нудна типобезопасность, то придется написать кастомный код для каждого типа отдельно. Такой подход подвержен ошибкам, очень многословен и нарушает принцип DRY(не повторять себя).
С другой стороны, я могу изменить свое бинарное дерево так, чтобы оно работало с типом interface{}. Это равнозначно разрешению на работу с любым типом. Но так я потеряю возможность проверки типов во время компиляции, а проверка типов при компиляции - одно из главных преимуществ Go. Кроме того, в Go нет возможности обработки слайса любого типа - слайс []string или []int нельзя назначить переменной типа interface{}.
В результате, до Go и дженериков, общие алгоритмы для слайсов, такие как map, reduce, filter, реализовывались в ручную для каждого типа отдельно. Это расстраивало разработчиков и было причиной критики языка Go.
Разработчики иметь возможность писать функции и структуры, в которых конкретный тип параметра или переменной можно было бы указать при использовании, при этом сохранить типобезопасность на этапе компиляции.
Для примера, возьмем две функции которые суммируют слайсы map[string]int64 и map[string]float64 соответственно:
copy
1// SumInts складывает вместе значения m.
2func SumInts(m map[string]int64) int64 {
3 var s int64
4 for _, v := range m {
5 s = v
6 }
7 return s
8}
9
10// SumFloats складывает вместе значения m.
11func SumFloats(m map[string]float64) float64 {
12 var s float64
13 for _, v := range m {
14 s = v
15 }
16 return s
17}
Было бы круто один раз написать функцию, которая умеет суммировать все значения любой числовой мапы, вмето написания функции под каждый тип.
Или еще один пример - две функции, которые умножают значения типа int и int16:
copy
1func DoubleInt(value int) int {
2 return value * 2
3}
4
5func DoubleInt16(value int16) int16 {
6 return value * 2
7}
Возможность написать одну, которая перемножают любые типы, это очень удобно. Неправда ли?
Почему так долго ждали?
Если аргументы в пользу дженериков такая так убедительны, то почему команде разработки Go понадобилось больше 10 лет для их реализации? На самом деле, эту проблему не так просто решить. Go делает упор на быстроте компиляции, понятном и читабельном коде, быстроте исполнения. Различные предполагаемы реализации ставили под угрозу одно ил несколько из этих преимуществ.
Но, как это часто бывает с открытым ПО, коллективное решение проблемы в конечном итоге привело к приемлемой реализации. Решение получилось универсальным, быстрым и эффективным. Но при этом достаточно гибким, чтобы соответствовать требованиям.
Дженерики а Go - резюме
Начиная с версии язык Go был расширен, чтобы дать возможность добавлять явно определенные структурные ограничения, называемые параметрами типа(type parameters), к объявлениям функций и объявлениям типов.
copy
1func F[T any](p T) { … }
2
3type M[T any] []
Список параметров типа [T any] использует квадратные скобки, но в остальном выглядит как обычный список параметров. Эти параметры типа затем могут использоваться обычными параметрами функции или в теле функции.
Общий(дженерик) код ожидает, что аргументы типа будут соответствовать определенным требованиям, которые называются ограничениями(constraints). Для каждого параметра типа должно быть определено ограничение:
copy
1func F[T Constraint](p T) {
2 // ...
3 }
Эти ограничение не более чем интерфейсные типы.
Ограничение параметра типа может могут ограничивать набор аргументов типа одним из трех способов:
произвольный(arbitrary) тип T ограничивается этим типом:
copy
1func F[T MyConstraint](p T) {
2 // ...
3 }
элемент приближения(approximation element) ~T ограничивается всеми типами, базовым типом которых является T
copy
1func F[T ~int] (p T) {
2 // ...
3 }
объединенный элемент T1 | T2 | … ограничивается любым из перечисленных элементов
copy
1func F[T ~int | ~string | ~float64] (p T) {
2 // ...
3 }
Когда универсальные функции и типы используют операторы для определенных параметров типа, эти параметры должны удовлетворять интерфейсу, определяемому ограничением параметра.
И самое главное, дизайн дженериков полностью обратно совмести с Go 1.
5,349 views
229
49
2 months ago 00:26:27 1
Новый тип тестов в Go / Сергей Петров (Selectel)
2 months ago 00:35:39 1
Ужасный Golang. Как потерять 100млн / Юрий Бедарев (Утконос ОНЛАЙН)
2 months ago 00:32:55 1
Что дженерики нам готовят / Павел Грязнов (Evrone)
2 months ago 00:14:54 40
Тадалафил в спорте: краткий обзор. Пампинг, выносливость, настроение, тестостерон, никотин и другое
2 months ago 01:21:44 1
Олександр Белинский (Generic Doom Band Name) про новый альбом, видеомейкинг и собственный лейбл
2 months ago 00:51:54 1
Почему Golang такой странный / Филипп Кулин (Дремучий лес)
2 months ago 00:48:54 1
Дженерики в Go / Илья Глухов (SibEDGE)
2 months ago 00:36:10 1
PHP generics / Антон Сухачёв (cdnnow!)
2 months ago 00:44:55 1
Выходя за рамки ООП. Разработка расширений для PHP... на PHP! / Александр Лисаченко (Docler Holding)
2 months ago 00:11:54 1
Python : Ускорение на максимум! Все новые возможности в одном видео!
2 months ago 00:44:06 5
Обвал в цене Brent, прогноз по индексу Мосбиржи, IPO Рольф, дивгэп Татнефти. Рынок Китая рухнул
2 months ago 02:23:10 1
Алексей Водовозов. Пациент экономный (и немного об оспе обезьян)
2 months ago 02:33:47 1
Иммунитет против раковых клеток | Anti-cancer defense inside us. (ENG subs)
2 months ago 00:05:33 1
Кровная месть - новое в отношениях высших государственных служащих РФ
2 months ago 00:29:58 3
Озон фармацевтика - все что нужно знать о фарме в России
3 months ago 09:32:48 1
Программирование на Go — курс Golang с бонусными проектами, машинный перевод на русский.
3 months ago 03:59:33 1
C# Полный курс бесплатно / для Unity / на русском / машинный перевод яндекса
3 months ago 00:12:02 1
Болванки дженерик домов для HUB локации в игре [ time lapse RPG maker MZ] #rpgmaker
3 months ago 00:16:08 1
Фармакодинамика / Юрий Киселев на ПостНауке
3 months ago 00:37:01 1
Генно-инженерные биопрепараты и ревматоидный артрит: возможности и безопасность
4 months ago 00:12:46 1
💥Самый честный обзор фильма [МОРТАЛ КОМБАТ] 2021| Это вам не фильм Смертельная Битва 1995
4 months ago 00:30:57 1
Фазы КИ/Дженерики
5 months ago 00:04:38 1
Лекарства В Турции
5 months ago 02:41:03 1
Типизированный Python для профессиональной разработки — теория и практика [2022]