如何确保在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>
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")
})
}