Дженерик-типы и вывод
Следом Миша обобщил очередь задач: она существовала в двух версиях — под строковые имена и под числовые идентификаторы. Один дженерик-тип заменил обе копии. Сергей закрыл тикет о дублирующемся коде.
параметры типа бывают не только у функций, но и у типов — Stack[T]; а при вызове тип обычно выводится из аргументов и указывать его не нужно.
Дженерик-тип
Классика — стек:
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
v := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return v, true
}
Stack[int] и Stack[string] — разные конкретные типы, у каждого свои методы. Использование ничем не отличается от обычного типа:
s := &Stack[int]{}
s.Push(1)
s.Push(2)
v, ok := s.Pop() // v имеет тип int
Похожим образом строят дженерик-кэш, очередь, множество — контейнеры, где логика не зависит от хранимого типа. Именно так Миша заменил две копии кэша метаданных.
Вывод типов
В большинстве вызовов тип можно не указывать — компилятор выводит его из аргументов:
first([]int{1, 2, 3}) // T = int
contains([]string{"a"}, "b") // T = string
Явно тип пишут, когда вывести его не из чего, или когда хотят зафиксировать, не полагаясь на вывод.
Методы дженерик-типа
Методы дженерик-типа используют его параметры типа как обычные типы: Push(v T) принимает тот же T, что и сам стек. Внутри методов параметры типа ведут себя как «тип, о котором известно только ограничение».
Вы узнаете:
- как устроены несколько параметров типа
Cache[K, V] - когда выбирать дженерик-функцию, а когда дженерик-тип
Проверьте себя
Что такое Stack[int]?
Когда параметр типа выводится автоматически?
Совместимы ли Stack[int] и Stack[string]?
правильных ответов
Дженерики работают и для типов: Stack[T] — семейство конкретных типов. Типы выводятся из аргументов; явное указание — редкость.
10 000 ₽ · 60 минут · онлайн