Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.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 保存对func的引用';这是一片_Go - Fatal编程技术网

Go 保存对func的引用';这是一片

Go 保存对func的引用';这是一片,go,Go,在这个程序中,我保存了对返回特定实现的函数的引用 在SpeakAll中,我调用每个函数来获取其对应的对象,并对其调用Speak 问题:无法遍历数组并获取输出 您的问题是AddAnimal被定义为Zoo类型的方法接收器,而不是*Zoo类型。这意味着当您调用z.AddAnimal(catFunc)时,您将动物园(包括切片动物)的副本传递给该方法,然后该方法将函数附加到原始动物园(而不是原始动物园)的副本上 将方法更改为如下所示的指针接收器,它将接收指向原始结构的指针: func (zoo *Zoo

在这个程序中,我保存了对返回特定实现的函数的引用

在SpeakAll中,我调用每个函数来获取其对应的对象,并对其调用Speak

问题:无法遍历数组并获取输出


您的问题是AddAnimal被定义为Zoo类型的方法接收器,而不是*Zoo类型。这意味着当您调用z.AddAnimal(catFunc)时,您将动物园(包括切片动物)的副本传递给该方法,然后该方法将函数附加到原始动物园(而不是原始动物园)的副本上

将方法更改为如下所示的指针接收器,它将接收指向原始结构的指针:

func (zoo *Zoo) AddAnimal(animal func() IAnimal) {
需要考虑的其他事项:

1-不需要以下代码-如果切片为nil,append将创建切片:

if zoo.Animals == nil {
    zoo.Animals = make([]func() IAnimal, 0)
}
2-在Go中,通常不在接口的名称前加I

3-如果您真的有一个包含单个切片的Zoo,您可以只向自定义切片类型添加方法:

type Zoo []func() IAnimal

func (zoo *Zoo) AddAnimal(animal func() IAnimal) {
    *zoo = append(*zoo, animal)
}

func (zoo Zoo) SpeakAll() {
    for _, animal := range zoo {
        fmt.Println(animal().Speak())
    }
}


func main() {
    catFunc := func() IAnimal {return Cat{}}
    dogFunc := func() IAnimal {return Dog{}}

    var z Zoo

    z.AddAnimal(catFunc)
    z.AddAnimal(dogFunc)

    z.SpeakAll()
} 

您需要将AddAnimal作为指针上的方法,例如
func(zoo*zoo)AddAnimal(animal func()IAnimal){
感谢@mkoprivaHi Colin,可以从零indiex开始从动物园移除动物,
SpeakAll方法中的数组移位
方法直到切片为空,再次使SpeakAll方法成为指针接收器,然后在范围迭代后截断切片。
type Zoo []func() IAnimal

func (zoo *Zoo) AddAnimal(animal func() IAnimal) {
    *zoo = append(*zoo, animal)
}

func (zoo Zoo) SpeakAll() {
    for _, animal := range zoo {
        fmt.Println(animal().Speak())
    }
}


func main() {
    catFunc := func() IAnimal {return Cat{}}
    dogFunc := func() IAnimal {return Dog{}}

    var z Zoo

    z.AddAnimal(catFunc)
    z.AddAnimal(dogFunc)

    z.SpeakAll()
}