douhu8851 2017-03-09 23:56
浏览 8
已采纳

将对func的引用保存在切片中

In this program I'm saving references to the functions that are returning specific implementations in a slice.

Within SpeakAll I'm calling each function to get it's corresponding object and calling Speak on it.

Issue: Unable to iterate through array and get an output

Go Playground

package main

import "fmt"

type IAnimal interface {
    Speak() string
}

type Cat struct {}
func (c Cat) Speak() string {
    return "meow!"
}

type Dog struct {}
func (d Dog) Speak() string {
    return "woof!"
}

type Zoo struct {
    Animals []func() IAnimal
}

func (zoo Zoo) AddAnimal(animal func() IAnimal) {
    if zoo.Animals == nil {
        zoo.Animals = make([]func() IAnimal, 0)
    }
    zoo.Animals = append(zoo.Animals, animal)
}

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


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

    z := Zoo{}

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

    z.SpeakAll()
}
  • 写回答

1条回答 默认 最新

  • dougaodi8895 2017-03-10 00:18
    关注

    Your problem is that AddAnimal has been defined as a method receiver on the Zoo type, not the *Zoo type. This means that when you call z.AddAnimal(catFunc) you pass a copy of the Zoo (including the slice Animals) to the method, which then appends the function to this copy of the original Zoo, but not the original Zoo.

    Change the method to a pointer receiver like this, and it will receive a pointer to the original struct:

    func (zoo *Zoo) AddAnimal(animal func() IAnimal) {
    

    Some additional things to consider:

    1 - You don't need the following code - append will create the slice if it's nil:

    if zoo.Animals == nil {
        zoo.Animals = make([]func() IAnimal, 0)
    }
    

    2 - In Go you generally don't prefix names with I for interface.

    3 - If you really have a Zoo with a single slice in it, you could instead just add methods to a custom slice type:

    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()
    } 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 Python如何后台操作Vmwake虚拟机键鼠
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容