gpt4 book ai didi

go - 在 slice 中保存对函数的引用

转载 作者:数据小太阳 更新时间:2023-10-29 03:37:21 25 4
gpt4 key购买 nike

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

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

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

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()
}

最佳答案

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

像这样将方法更改为指针接收器,它将接收到指向原始结构的指针:

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

需要考虑的一些额外事项:

1 - 您不需要以下代码 - 如果它为 nil,append 将创建 slice :

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

2 - 在 Go 中,您通常不会在名称前加上 I 作为接口(interface)前缀。

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

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()
}

关于go - 在 slice 中保存对函数的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42707769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com