【问题标题】:Generic function using embeddable structs使用可嵌入结构的通用函数
【发布时间】:2014-02-26 01:03:23
【问题描述】:

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

我是 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”方法。

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

谢谢

【问题讨论】:

  • 在 Go 中处理类泛型函数的常用方法是通过接口。不过,您的示例似乎相当抽象,因此很难给出具体建议。
  • 我很难理解您要做什么。你能用泛型语言(如 C#)提供一个类似的例子吗?

标签: reflection go


【解决方案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”的不同函数名称,没有任何类型无关的数据结构可以帮助您神奇地调用正确的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多