- наш обучающий телеграм канал для 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
180
34
7 months ago 00:58:34 1
TypeScript от А до Я — часть 2: classes, extends, implements, generics, utility types
7 months ago 00:50:33 1
Рено Сценик 2007 (F4R 2.0): Дешевый “контракт“ из Минска
7 months ago 00:34:33 1
Как на самом деле устроен тип Map в Golang? | Golang под капотом
7 months ago 00:16:12 1
🍇 Виноград болеть не будет. Рабочая СХЕМА ОБРАБОТКИ от основных болезней из ДОСТУПНЫХ ПРЕПАРАТОВ.
7 months ago 00:32:12 1
Односвязный список C#
7 months ago 00:19:37 1
ТОП-5 ПРИЧИН ВЫСОКОГО ДАВЛЕНИЯ ПРИ ГИПЕРТОНИИ! ПОЧЕМУ СКАЧЕТ ДАВЛЕНИЕ? УЗНАЙ ПОКА НЕ ПОЗДНО!
7 months ago 00:55:16 1
5 Workflows to Create AI Images That Don’t Look Generic
7 months ago 00:16:35 1
Про вредность мелатонина при СБН.
7 months ago 00:57:11 1
Жировой гепатоз. Гепатолог Тэя Розина и @Доктор Утин о защите печени
7 months ago 00:24:04 1
Гепатит С - НЕ ПРИГОВОР! Санкт Петербург. Полный выпуск. Юрий Сердцев
7 months ago 02:06:11 1
Новый Ковид. Чайный гриб от диабета. Колоноскопия и волокна.
7 months ago 01:11:12 1
Артемий Лебедев про работу с государством, воспитание 10 детей и поездку в Мариуполь
7 months ago 00:19:14 1
Пробуем дженерики Go на практике
8 months ago 00:35:28 2
САМЫЙ ПОЛЕЗНЫЙ хук для ОПТИМИЗАЦИЙ в React | React Hooks
8 months ago 00:56:16 5
Génériques d’émissions télé de 1970 à 1979 (en français)
8 months ago 02:23:10 1
Алексей Водовозов. Пациент экономный (и немного об оспе обезьян)
8 months ago 00:54:16 1
Как пройти СОБЕСЕДОВАНИЕ на C# & .Net РАЗРАБОТЧИКА?
8 months ago 00:16:20 1
Лекарства, БАД или диеты? Противостояние.
8 months ago 02:33:47 1
Иммунитет против раковых клеток | Anti-cancer defense inside us. (ENG subs)
8 months ago 02:02:48 1
КАНДИДА в кишках и в мозгах. Навалимся?
8 months ago 00:39:37 1
VIDEO N°80 MAINTENUE AVEC GENERIQUE
8 months ago 00:46:19 11
Я прошёл все портативные игры о человеке пауке и задушился.
8 months ago 00:04:13 1
Опасный препарат “Сонапакс“. Почему нужно прекратить его использование?