如何检查空结构?

新手上路,请多包涵

我定义了一个结构…

 type Session struct {
    playerId string
    beehive string
    timestamp time.Time
}

有时我给它分配一个空会话(因为 nil 是不可能的)

 session = Session{};

然后我想检查它是否为空:

 if session == Session{} {
     // do stuff...
}

显然这是行不通的。我怎么写呢?

原文由 Michael 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 530
2 个回答

您可以使用 == 与零值复合文字进行比较,因为 Session 中的所有字段都是 可比较 的:

 if (Session{}) == session  {
    fmt.Println("is zero value")
}

游乐场示例

由于 解析歧义,在 if 条件中,复合文字周围需要括号。

上面 == 的使用适用于所有字段都可 比较 的结构。如果结构包含不可比较的字段(切片、映射或函数),则必须将这些字段与它们的零值一一比较。

比较整个值的替代方法是比较必须在有效会话中设置为非零值的字段。例如,如果玩家 ID 在有效会话中必须为 != ““,请使用

if session.playerId == "" {
    fmt.Println("is zero value")
}

原文由 Cerise Limón 发布,翻译遵循 CC BY-SA 4.0 许可协议

这里还有 3 个建议或技巧:

有一个额外的领域

您可以添加一个附加字段来判断该结构是已填充还是为空。 I intentionally named it ready and not empty because the zero value of a bool is false , so if you create a new struct like Session{} 它的 ready 字段将自动 false 它会告诉你真相:准备好空结构(structit不是-y)。

 type Session struct {
    ready bool

    playerId string
    beehive string
    timestamp time.Time
}

初始化结构时,必须将 ready 设置为 true 。不再需要您的 isEmpty() 方法(尽管您可以根据需要创建一个),因为您可以只测试 ready 字段本身。

 var s Session

if !s.ready {
    // do stuff (populate s)
}

这一个额外的意义 bool 字段随着结构变大或者它包含不可比较的字段(例如切片, map 和函数值)而增加。

使用现有字段的零值

这与之前的建议类似,但它使用现有字段的零值,当结构不为空时,该字段被视为 _无效_。这个的可用性取决于实现。

例如,如果在您的示例中,您的 playerId 不能为空 string "" ,您可以使用它来测试您的结构是否为空:

 var s Session

if s.playerId == "" {
    // do stuff (populate s, give proper value to playerId)
}

在这种情况下,值得将此检查合并到 isEmpty() 方法中,因为此检查依赖于实现:

 func (s Session) isEmpty() bool {
    return s.playerId == ""
}

并使用它:

 if s.isEmpty() {
    // do stuff (populate s, give proper value to playerId)
}

使用指向您的结构的指针

第二个建议是使用指向您的结构的指针: *Session 。指针可以有 nil 值,所以你可以测试它:

 var s *Session

if s == nil {
    s = new(Session)
    // do stuff (populate s)
}

原文由 icza 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题