如何确保在struct中定义字段?

如何确保在struct中定义字段?

问题描述:

This might be a bit silly and I apologize if it is but how do I guarantee that a field is defined in a struct before I can use it?

Let me explain this with example:

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

Let's say there can be more animal structs in zoo array. Is there a better way to make sure that every animal must define activity function other than doing the following:

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

Using method doesn't look feasible here as implementation of activity is quite different for each animal. I was also thinking of using interface but then wouldn't I have to create a type of every animal?
The reason I'm not happy with the above if solution is that the check is done in runtime only. However, if that's the only way to approach this problem then I'm okay with that too.

这可能有点傻,很抱歉,但是我如何保证在 p>

让我用示例进行解释: p>

  package main 
 
import(
“ fmt  “ 
)
 
输入动物结构{
名称字符串
活动func()
} 
 
var大象=动物{
名称:” elephant“,
活动:func(){
  fmt.Println(“吃草”)
 fmt.Println(“ Stampede”)
},
} 
 
var狐猴=动物{
名称:“ lemur”,
活动:func(){  
 fmt.Println(“食用水果”)
 fmt.Println(“爬树”)
},
} 
 
func main(){
动物园:= []动物{
大象,  
狐猴,
 //这里还有更多
} 
 
 _,笼子:=范围动物园{
 cage.activity()
} 
 
} 
  code>   pre> 
 
 

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

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

 用于_,cage:= range zoo  {
 if cage.activity!= nil {
 cage.activity()
} 
} 
  code>  pre> 
 
 

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

The only way to statically ensure that the function is set for each value is to use methods and an interface. This requires a type for each kind of animal as you noted.

One approach to ensure that function is set a runtime is to use a factory function for creating animal values. This function can check that activity is not nil.

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

A variation is to build the zoo using function calls:

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