我已经实现了一个适用于切片的通用 Map 函数,并且我发现我的大型应用程序中有许多不同的结构具有相同的方法
GetID
。
此外,我一直发现自己需要从这些结构体的切片中获取 id 的切片。
所以我写了以下内容
type Object struct {
id *string
}
func (d *Object) GetID() string {
return *d.id
}
type Identifiable interface {
GetID() string
}
func GetID(o Identifiable) string {
return o.GetID()
}
func Map[S, T any](s []S, f func(S) T) []T {
res := make([]T, len(s))
for i, v := range s {
res[i] = f(v)
}
return res
}
但是当我尝试使用它时,就像下面的例子一样:
func main() {
id := "asd"
id2 := "dsa"
objects := []*Object{
&Object{id: &id},
&Object{id: &id2},
}
ids := Map(objects, GetID)
fmt.Println(ids)
}
我收到此错误
GetID 的类型 func(o Identifying) 字符串与 func(S) T 的推断类型 func(Object) T 不匹配
我真的不明白我应该在这里做什么。
为了方便起见,请参阅游乐场链接:link
这里的问题是,即使
*Object
可以隐式转换为 Identifiable
并因此传递给接受 Identifiable
的函数,该函数的类型仍然是 func(Identifiable) string
而不是 func(*Object) string
。
即使没有泛型也可能出现这种情况;例如,这个:
var _ func(*Object) string = GetID
将因以下错误而失败:
cannot use GetID (value of type func(o Identifiable) string) as func(*Object) string value in variable declaration
既然你在这里使用泛型,最简单的解决方法就是使
GetID
泛型:
func GetID[T Identifiable](o T) string {
return o.GetID()
}
[游乐场链接]