使用可嵌入结构的通用函数

时间:2014-02-25 08:56:19

标签: reflection go

我正在尝试编写一个函数,它将处理某种类型的对象,并调用作为其中一个args传递的某个方法。由于没有继承或泛型,我使用嵌入。 (我不能使用接口,因为你只能在其中定义方法,我也需要结构字段。)

我是Go的新手,所以我肯定做错了什么。这是我的代码的简化版本:

http://play.golang.org/p/r0mtDXtmWc

package main

import "fmt"
import "reflect"

type Animal struct {
    Type string
}

type Dog struct {
    Animal
}

type Cat struct {
    Animal
}

func (d *Dog) SayWoof() {
    fmt.Println("WOOF")
}

func (c *Cat) SayMeouw() {
    fmt.Println("MEOUW")
}

func CallMethod(animal interface{}, baseAnimal *Animal, methodName string) {
    fmt.Println("Animal type: ", baseAnimal.Type)

    method := reflect.ValueOf(animal).MethodByName(methodName)
    if !method.IsValid() {
        return
    }

    method.Call([]reflect.Value{})
}

func main() {
    dog := &Dog{}
    dog.Type = "Dog" // for some reason dog := &Dog{Type: "Dog"} doesn't compile

    cat := &Cat{}
    cat.Type = "Cat"

    CallMethod(dog, &dog.Animal, "SayWoof")
    CallMethod(cat, &cat.Animal, "SayMeouw")
}

输出:

Animal type:  Dog
WOOF
Animal type:  Cat
MEOUW

这段代码可以工作,但我基本上需要传递一个对象两次:首先是一个动态调用方法的接口,然后是嵌入式(“父”)对象来访问它的字段。

我更喜欢像

这样的东西
func CallMethod(animal Animal, methodName string)

但是如果将Dog对象转换为Animal,就像这样:

CallMethod(dog.Animal, "SayWoof")

它显然不起作用,因为在Animal中没有定义“SayWoof”方法。

所以问题是:有没有办法将子对象传递给函数一次并可以访问其所有反射数据?

由于

1 个答案:

答案 0 :(得分:1)

package main

import "fmt"

type Animal interface {
    Speak()
}

type Dog struct {
}

type Cat struct {
}

func (d *Dog) Speak() {
    fmt.Println("Woof")
}

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

func Speaketh(a Animal) {
    a.Speak()
}

func main() {
    dog := Dog{}
    cat := Cat{}
    Speaketh(&dog)
    Speaketh(&cat)
}

您究竟期望使用泛型语言来解决您的问题吗?这是一个诚实的问题。使用不同的函数名称,您想要调用“SayMeow”和“SayWoof”,没有类型不可知的数据结构将帮助您神奇地调用正确的东西。