如何在具有处理函数时嵌入类型?

时间:2016-05-17 20:13:17

标签: go

我正在使用一个库来实现一个接受处理程序的类型,并在它应该的时候为你调用它们。我想创建一个嵌入类型的超类型,并具有超出嵌入类型的属性。 我希望能够在处理程序中使用这些属性。

使用我的类型作为参数失败了类型检查,使用处理程序decl中的基类型工作,但后来我无法访问新字段。我是新来的,&我想知道如何做到这一点,或者在更改库以启用时建议什么(接口而不是处理程序decl?)...

受挫的例子:

    package main

    type Animal struct {
        Color   string
        feeders map[string]feeder
    }
    type feeder func(*Animal, string) string

    func (a *Animal) addFeeder(name string, fn feeder) {
        a.feeders[name] = fn
    }

    type mamal struct {
        Animal
        hair string
    }

    func feedHuman(m *mamal, food string) string {
        return "you got " + m.Color + " " + m.hair + " hair in your " + food
    }

    func main() {
        a := mamal{Animal{Color: "red"}, "bushy"}
        a.addFeeder("man", feedHuman)
        // fails to compile feedHuman needs to take *Animal but then cant access hair"
    }

1 个答案:

答案 0 :(得分:0)

你是对的,你做不到,因为mamal不是动物。 go中没有继承,所以这不是解决方案。但是你可以通过接口实现这种行为。顺便说一下,你的代码不起作用,因为你没有初始化馈线地图,所以你会在编译后遇到问题。

解决方案1:使用类型断言

package main

import "fmt"

type Animal struct {
    Color   string
    feeders map[string]feeder
}
type feeder func(interface{}, string) string

func (a *Animal) addFeeder(name string, fn feeder) {
    a.feeders[name] = fn
}

type mamal struct {
    Animal
    hair string
}

func feedHuman(i interface{}, food string) string {
    m := i.(mamal)
    return "you got " + m.Color + " " + m.hair + " hair in your " + food
}

func main() {
    a := mamal{Animal{feeders: make(map[string]feeder), Color: "red"}, "bushy"}
    a.addFeeder("man", feedHuman)
    fmt.Println(a.feeders["man"](a, "pineapple"))
    // => you got red bushy hair in your pineapple
}

这有点危险,因为如果你传递的界面不是mamal,那就会引起恐慌。

第二种解决方案:使用Feedder界面

package main

import "fmt"

type Feeder interface {
    Feed(string) string
}

type Animal struct {
    Color   string
    feeders map[string]Feeder
}

func (a *Animal) addFeeder(name string, feeder Feeder) {
    a.feeders[name] = feeder
}

type mamal struct {
    Animal
    hair string
}

func (m *mamal) Feed(food string) string {
    return "you got " + m.Color + " " + m.hair + " hair in your " + food
}

func main() {
    a := &mamal{Animal{Color: "red", feeders: make(map[string]Feeder)}, "bushy"}
    a.addFeeder("man", a)
    fmt.Println(a.feeders["man"].Feed("pineapple"))
    // you got red bushy hair in your pineapple
}

虽然它的工作原理同样好,但它将处理程序的数量限制为一个,所以我认为这不是你想要的。