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

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配