英文:
Nested generic types: Reuse function's Type parameter
问题
给定以下定义:
type Collector[T, C any] interface {
Collect(T, C) C
}
type mapCollector[K comparable, V any] struct {
GetKey func(result V) K
}
func (m *mapCollector[K, V]) Collect(value V, c *sync.Map) *sync.Map {
c.Store(m.GetKey(value), value)
return c
}
我正在尝试为mapCollector
编写一个模板化的make函数。
这个不起作用:
func MakeUserMapCollector[K UserId, V User]() *mapCollector[K, V] {
c := mapCollector[K, V]{
GetKey: func(user V) K {
return user.getId()
}
}
return &c
}
相反,我必须重复一遍:
func MakeUserMapCollector() *mapCollector[UserId, User] {
c := mapCollector[UserId, User]{
GetKey: func(user User) UserId {
return user.getId()
}
}
}
有没有办法重用MakeUserMapCollector
的类型参数来在函数中声明类型?
英文:
Given the following definitions:
type Collector[T, C any] interface {
Collect(T, C) C
}
type mapCollector[K comparable, V any] struct {
GetKey func(result V) K
}
func (m *mapCollector[K, V]) Collect(value V, c *sync.Map) *sync.Map {
c.Store(m.GetKey(value), value)
return c
}
I am trying to write a templated make function for mapCollector
.
This does not work
func MakeUserMapCollector[K UserId, V User]() *mapCollector[K, V] {
c := mapCollector[K, V]{
GetKey: func(user V) K {
return user.getId()
}
}
return &c
}
Instead I have to be repetitive
func MakeUserMapCollector() *mapCollector[UserId, User] {
c := mapCollector[UserId, User]{
GetKey: func(user User) UserId {
return user.getId()
}
}
}
Is there a way to reuse the MakeUserMapCollector
type parameters to declare types in the function?
答案1
得分: 2
你可以创建一个通用的构造函数,该函数接受一个用于"collection"的函数,并将其传递给你的mapCollector
结构体。
代码如下所示:
func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
return &mapCollector[K, V]{
GetKey: collect,
}
}
然后,你可以使用你的类型作为类型参数以及你的"collection"函数调用构造函数:
mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
完整示例(Go Playground):
package main
import (
"fmt"
)
type mapCollector[K comparable, V any] struct {
GetKey func(result V) K
}
func (m mapCollector[K, V]) Collect(result V) K {
return m.GetKey(result)
}
type UserId string
type User struct {
Id UserId
}
func (u User) GetId() UserId {
return u.Id
}
func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
return &mapCollector[K, V]{
GetKey: collect,
}
}
func main() {
u := User{
Id: "12",
}
mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
fmt.Println(mc.Collect(u))
}
英文:
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:
func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
return &mapCollector[K, V]{
GetKey: collect,
}
}
Then you can call the constructor function with your types as type parameters and your "collection" function:
mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
Full example (Go Playground):
package main
import (
"fmt"
)
type mapCollector[K comparable, V any] struct {
GetKey func(result V) K
}
func (m mapCollector[K, V]) Collect(result V) K {
return m.GetKey(result)
}
type UserId string
type User struct {
Id UserId
}
func (u User) GetId() UserId {
return u.Id
}
func MakeUserMapCollector[K comparable, V any](collect func(result V) K) *mapCollector[K, V] {
return &mapCollector[K, V]{
GetKey: collect,
}
}
func main() {
u := User{
Id: "12",
}
mc := MakeUserMapCollector[UserId, User](func(result User) UserId { return result.GetId() })
fmt.Println(mc.Collect(u))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论