Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 当类型具有处理函数时,如何嵌入它?_Go - Fatal编程技术网

Go 当类型具有处理函数时,如何嵌入它?

Go 当类型具有处理函数时,如何嵌入它?,go,Go,我正在使用一个库,它实现了一个类型,该类型接受处理程序并在应该的时候为您调用它们。我想创建一个超类型,该超类型嵌入该类型,并且具有超出嵌入类型的属性。 我希望能够在处理程序中使用这些属性 使用my type作为参数会导致类型检查失败,使用处理程序decl中的基类型会起作用,但是我无法访问新字段。我是新手,希望知道如何做到这一点,或者在更改库以启用(接口而不是处理程序decl?)时有什么建议 人为的例子: package main type Animal struct {

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

使用my type作为参数会导致类型检查失败,使用处理程序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"
    }

你是对的,你不能那样做,因为马玛耳不是动物。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,它将死机

第二种解决方案:使用馈线接口

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
}

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

我同意#2与这个想法不匹配#1有承诺,但违反了图书馆的所有其他用户。因此,也许我建议使用接口{}创建一个新的通用处理程序加法器,并将当前的处理程序修改为调用它。所以现在基本表单是泛型的,但是对于不扩展类型的人,外部接口保持不变。很高兴这有帮助。如果您的新解决方案适合您的需要,那么就可以了。