Пропозал добавляет возможность объявлять типы-параметры у дженерик-методов, а не только у структур и обычных функций.
На простом примере: допустим, есть у нас структура ответа c дженерик-типом:
type Response[T any] struct {
Data T
Err error
}
И получая ответ для типа User, мы хотим его замапить в другой тип - UserDTO. Если ты не знаком с дженериками, то интуитивно хочется сделать что-то такое:
func (Response[T]) Map[U any] funcname...
Но так сделать нельзя. Сейчас Go позволяет на структуру навешивать методы только с тем типом, который определен для структуры. Чтобы решить проблему с маппером выше сейчас нужно определять глобальную функцию:
func MapResponse[T any, U any](r Response[T], f func(T) U) Response[U] {
if r.Err != nil {
return Response[U]{Err: r.Err}
}
return Response[U]{Data: f(r.Data)}
}
и вызывать ее потом следующим образом:
resp := GetUserFromDB(1)
dtoResp := MapResponse(resp, func(u User) UserDTO {
return UserDTO{Name: u.Name}
})
Когда пропозал завезут в новую версию, дженерик-структуры получат возможность навешивать методы с собственными параметрами:
type Response[T any] struct {
Data T
Err error
}
func (r Response[T]) Map[U any](f func(T) U) Response[U] {
if r.Err != nil {
return Response[U]{Err: r.Err}
}
return Response[U]{Data: f(r.Data)}
}
// использование:
dtoResp := GetUserFromDB(1).Map(func(u User) UserDTO {
return UserDTO{Name: u.Name}
})
Куда это красиво ляжет? Например, на обработку коллекций или потоков данных. Можно будет использовать цепочку вызовов:
mySlice.Map(transform).Filter(check).Collect()
В целом, после первичной стадии отторжения дженериков пару лет назад - я плавно перешел в стадию их принятия, особенно когда на работе появился проект, где мы их начали использовать. Сейчас же, когда их использование стало совсем привычной вещью - этот пропозал выглядит очень полезным и явно двигает систему дженериков в Go в нужную сторону.