dtp19819 2018-02-24 20:40
浏览 59
已采纳

如何确保在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.

  • 写回答

1条回答 默认 最新

  • duanjiuhong5843 2018-02-24 20:55
    关注

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

报告相同问题?

悬赏问题

  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?