Golang 继承 - 不能使用 (type func(d Dog)) 作为 func(animal Animal) 类型
Golang inheritance - Cannot use (type func(d Dog)) as the type func(animal Animal)
我想写一个方法 callGetName
,它可以将 getCatName
和 getDogName
方法作为参数,而我的 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{})
}
我想写一个方法 callGetName
,它可以将 getCatName
和 getDogName
方法作为参数,而我的 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{})
}