嵌套泛型类型:重用函数的类型参数

huangapple go评论104阅读模式
英文:

Nested generic types: Reuse function's Type parameter

问题

给定以下定义:

  1. type Collector[T, C any] interface {
  2. Collect(T, C) C
  3. }
  4. type mapCollector[K comparable, V any] struct {
  5. GetKey func(result V) K
  6. }
  7. func (m *mapCollector[K, V]) Collect(value V, c *sync.Map) *sync.Map {
  8. c.Store(m.GetKey(value), value)
  9. return c
  10. }

我正在尝试为mapCollector编写一个模板化的make函数。
这个不起作用:

  1. func MakeUserMapCollector[K UserId, V User]() *mapCollector[K, V] {
  2. c := mapCollector[K, V]{
  3. GetKey: func(user V) K {
  4. return user.getId()
  5. }
  6. }
  7. return &c
  8. }

相反,我必须重复一遍:

  1. func MakeUserMapCollector() *mapCollector[UserId, User] {
  2. c := mapCollector[UserId, User]{
  3. GetKey: func(user User) UserId {
  4. return user.getId()
  5. }
  6. }
  7. }

有没有办法重用MakeUserMapCollector的类型参数来在函数中声明类型?

英文:

Given the following definitions:

  1. type Collector[T, C any] interface {
  2. Collect(T, C) C
  3. }
  4. type mapCollector[K comparable, V any] struct {
  5. GetKey func(result V) K
  6. }
  7. func (m *mapCollector[K, V]) Collect(value V, c *sync.Map) *sync.Map {
  8. c.Store(m.GetKey(value), value)
  9. return c
  10. }

I am trying to write a templated make function for mapCollector.
This does not work

  1. func MakeUserMapCollector[K UserId, V User]() *mapCollector[K, V] {
  2. c := mapCollector[K, V]{
  3. GetKey: func(user V) K {
  4. return user.getId()
  5. }
  6. }
  7. return &c
  8. }

Instead I have to be repetitive

  1. func MakeUserMapCollector() *mapCollector[UserId, User] {
  2. c := mapCollector[UserId, User]{
  3. GetKey: func(user User) UserId {
  4. return user.getId()
  5. }
  6. }
  7. }

Is there a way to reuse the MakeUserMapCollector type parameters to declare types in the function?

答案1

得分: 2

你可以创建一个通用的构造函数,该函数接受一个用于"collection"的函数,并将其传递给你的mapCollector结构体。

代码如下所示:

  1. func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
  2. return &mapCollector[K, V]{
  3. GetKey: collect,
  4. }
  5. }

然后,你可以使用你的类型作为类型参数以及你的"collection"函数调用构造函数:

  1. mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })

完整示例(Go Playground):

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type mapCollector[K comparable, V any] struct {
  6. GetKey func(result V) K
  7. }
  8. func (m mapCollector[K, V]) Collect(result V) K {
  9. return m.GetKey(result)
  10. }
  11. type UserId string
  12. type User struct {
  13. Id UserId
  14. }
  15. func (u User) GetId() UserId {
  16. return u.Id
  17. }
  18. func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
  19. return &mapCollector[K, V]{
  20. GetKey: collect,
  21. }
  22. }
  23. func main() {
  24. u := User{
  25. Id: "12",
  26. }
  27. mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
  28. fmt.Println(mc.Collect(u))
  29. }
英文:

You can create a generic constructor function that accepts a function for "collection" and then passes it to your mapCollector struct.

That would look something like this:

  1. func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
  2. return &mapCollector[K, V]{
  3. GetKey: collect,
  4. }
  5. }

Then you can call the constructor function with your types as type parameters and your "collection" function:

  1. mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })

Full example (Go Playground):

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type mapCollector[K comparable, V any] struct {
  6. GetKey func(result V) K
  7. }
  8. func (m mapCollector[K, V]) Collect(result V) K {
  9. return m.GetKey(result)
  10. }
  11. type UserId string
  12. type User struct {
  13. Id UserId
  14. }
  15. func (u User) GetId() UserId {
  16. return u.Id
  17. }
  18. func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
  19. return &mapCollector[K, V]{
  20. GetKey: collect,
  21. }
  22. }
  23. func main() {
  24. u := User{
  25. Id: "12",
  26. }
  27. mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
  28. fmt.Println(mc.Collect(u))
  29. }

huangapple
  • 本文由 发表于 2022年9月27日 02:02:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/73858175.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定