Golang 继承 - 不能使用 (type func(d Dog)) 作为 func(animal Animal) 类型

Golang inheritance - Cannot use (type func(d Dog)) as the type func(animal Animal)

我想写一个方法 callGetName,它可以将 getCatNamegetDogName 方法作为参数,而我的 IDE 告诉我:

Cannot use 'getDogName' (type func(d Dog)) as the type func(animal Animal)

package main

type Animal struct {
    Name string
}
type Cat struct {
    Animal
}
type Dog struct {
    Animal
}

func getCatById(c Cat) {}
func validateDogNames(d Dog) {}

func invokeFunc(f func(animal Animal)) {}

func main() {
    invokeFunc(getCatById)
    invokeFunc(validateDogNames)
}

我试着分析了一下原因,可能是因为golang支持多重继承?

如果我在做一些愚蠢的事情或者有更好的方法来实现这一点,请告诉我?

========

更多关于我尝试这个的原因:在 go-kit 框架中,我必须为定义的每个服务方法编写 makeEndpoint 函数。我用 reflect 来采用如下的通用 makeEndpoints:

func NewProductEndpoints() ProductEndpoints {
    ps := service.NewProductService()
    return ProductEndpoints{
        GetProductById: makeEndpoint(ps, util.GetFunctionName(ps.GetProductById)),
        CreateProduct: makeEndpoint(ps, util.GetFunctionName(ps.CreateProduct)),
    }
}

func makeEndpoint(s service.ProductService, funcName string) kitEndpoint.Endpoint {
    return func(ctx context.Context, request interface{}) (response interface{}, err error) {
        req := request.(domain.ProductDTO)
        currFunc := reflect.ValueOf(s).MethodByName(funcName)
        args := []reflect.Value{reflect.ValueOf(req)}
        res := currFunc.Call(args)[0]
        return res, nil
    }
}

想知道有没有更好的实现方式。提前致谢。

所以你在以相当 OOP 的方式思考,Go 没有继承(澄清它有结构嵌入,这就是你在第一个例子中所做的)。我们倾向于赞成组合来解决问题。

解决问题的一种方法如下所示。

package main

import (
    "fmt"
)

type Namer interface {
    Name() string
}

type Cat struct {
    name string
}

func (c Cat) Name() string {
    return c.name
}

type Dog struct {
    name string
}

func (d Dog) Name() string {
    return d.name
}

func PetName(n Namer) {
    fmt.Println(n.Name())
}

func main() {
    PetName(Dog{name: "Fido"})
    PetName(Cat{name: "Mittens"})
}

名称可以改进,但它应该作为可以采用的方法的基本示例。

编辑:示例基于下方留下的评论

package main

import (
    "fmt"
)

type Invoker interface {
    Invoke()
}

type Dog struct{}

func (Dog) Bark() {
    fmt.Println("Woof")
}
func (d Dog) Invoke() {
    d.Bark()
}

type Cat struct{}

func (Cat) Meow() {
    fmt.Println("Meow")
}
func (c Cat) Invoke() {
    c.Meow()
}

func CallFunc(i Invoker) {
    i.Invoke()
}

func main() {
    CallFunc(Cat{})
    CallFunc(Dog{})
}