go - 如何确保在结构中定义字段?

标签 go struct

这可能有点傻,如果是的话,我深表歉意,但我如何保证在我可以使用它之前在结构中定义了一个字段?

让我用例子来解释一下:

package main

import (
    "fmt"
)

type animal struct {
    name     string
    activity func()
}

var elephant = animal{
    name: "elephant",
    activity: func() {
        fmt.Println("Eat grass")
        fmt.Println("Stampede")
    },
}

var lemur = animal{
    name: "lemur",
    activity: func() {
        fmt.Println("Eat fruits")
        fmt.Println("Climb trees")
    },
}

func main() {
    zoo := []animal{
        elephant,
        lemur,
        // more goes here
    }

    for _, cage := range zoo {
        cage.activity()
    }

}

https://play.golang.org/p/0nXNk0DMuVd

假设 zoo 数组中可以有更多的 animal 结构。除了执行以下操作之外,是否有更好的方法来确保每个动物都必须定义 activity 函数:

for _, cage := range zoo {
    if cage.activity != nil {
      cage.activity()
    }
}

使用 method 在这里看起来不可行,因为每个动物的 activity 的实现都大不相同。我也在考虑使用 interface,但我不是必须为每种动物创建一个类型吗?
我对上面的 if 解决方案不满意的原因是检查仅在运行时完成。但是,如果这是解决此问题的唯一方法,那么我也同意。

最佳答案

静态确保为每个值设置函数的唯一方法是使用方法和接口(interface)。正如您所指出的,这需要每种动物的类型。

确保函数设置为运行时的一种方法是使用工厂函数来创建动物值。此函数可以检查事件是否为零。

func newAnimal(name string, activity func()) animal {
   if activity == nil {
      panic("missing activity for " + name)
   }
   return animal{name, activity}
}

var elephant = newAnimal("elephant", func() {
    fmt.Println("Eat grass")
    fmt.Println("Stampede")
})

var lemur = newAnimal("lemur", func() {
    fmt.Println("Eat fruits")
    fmt.Println("Climb trees")
})

一种变体是使用函数调用来构建动物园:

type zoo []animal

func addAnimal(name string, activity func()) {
   if activity == nil {
      panic("missing activity for " + name)
   }
   zoo = append(zoo, animal{name, activity})
}

func init() {
  addAnimal("elephant", func() {
    fmt.Println("Eat grass")
    fmt.Println("Stampede")
  })
  addAnimal("lemur", func() {
    fmt.Println("Eat fruits")
    fmt.Println("Climb trees")
  })
}

关于go - 如何确保在结构中定义字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48967382/

相关文章:

go - 我靠运气解决的Golang僵局,需要说明

go - 语法错误 : unexpected name, 需要分号或换行符

C通过引用或按值将结构数组传递给函数

c - sizeof 匿名嵌套结构

go - 超时停止 goroutine 执行

sockets - 为什么连接读取返回缓冲区的长度,而不是真正发送?

google-app-engine - 是否可以获取GAE 上的日志点?

c - 未格式化的 C 文件输入/输出

c++ - 为函数内部的结构分配和初始化值

c - 在 C 结构中的声明时初始化指针