Golang:在传递 func 作为参数时不能使用接口而不是结构

问题描述 投票:0回答:1

我已经实现了一个适用于切片的通用 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

go generics
1个回答
0
投票

这里的问题是,即使

*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()
}

[游乐场链接]

© www.soinside.com 2019 - 2024. All rights reserved.