gpt4 book ai didi

go - 您应该使用零 “enum”值来表示无效值吗

转载 作者:行者123 更新时间:2023-12-01 20:26:10 27 4
gpt4 key购买 nike

使用C已有几十年了,我养成了使用枚举的零值作为特殊的undefined/unknown/error值的习惯。多年来,我相信这可以为我节省数小时甚至数天的调试时间,但可以节省数月的调试时间,因为它可以使您在未初始化值时显而易见。 (对于具有合理的默认值且没有未初始化值的可能性的简单枚举,我不会这样做。)

在我看来,这种做法在Go中更加有用,因为值会自动为您初始化为零。但是,有人告诉我“惯用的” Go零值应该是有效值。我认为此“规则”是为结构发明的,在这种情况下(在没有构造函数的情况下)准备好使用新创建的“清零”结构是很有意义的,但是在某些情况下,没有逻辑默认值(对于结构和枚举)。

如果需要,这里有一个例子:

type Base int

const (
Invalid Base = iota
A
C
T
G
)

请注意,我已经在SO上对此问题进行了广泛搜索,但感到惊讶的是该特定主题尚未涵盖。我意识到我的问题有些主观,可能会被举报,但我认为这很有用。我正在寻找证据证明使用零值指示错误情况是可以接受的Go练习。此用法的任何示例,例如。从标准的Go库中获取,不胜感激。

最佳答案

真正的enum类型应仅从预定义的常量值列表中分配一个值。但是,go语言没有这种类型值强制。
go具有const,通常使用诸如int的派生类型。没有强制严格在预定义列表中的值的编译/运行时机制。

那么这实际上意味着什么?

您的枚举值是必需的还是可选的?也就是说,在反序列化“枚举”值时,是否:

  • 可选-然后使用零值表示默认值
  • 必需-然后零值表示初始化错误

  • 根据您的常见用例,选择以下两个选项之一。

    编辑:
    反序列化不是唯一的问题。分支枚举值时,必须格外小心。例如:
    type role int
    const (
    user role = iota
    helpdesk
    admin
    )

    func greet(r role) {
    switch r {
    case admin:
    fmt.Println("hi admin")
    case helpdesk:
    fmt.Println("hi helpdesk")
    default:
    fmt.Println("hi user") // right?
    }
    }

    这有效:
    var r role
    r = admin
    greet(r) // hi admin

    但是呢?
    r = 12
    greet(r) // 'hi user' ?!!

    因此,请确保仅对有效值进行花哨的验证:
    func validateRole(r role) (err error) {
    switch r {
    case user, helpdesk, admin: // all valid values
    default:
    err = fmt.Errorf("invalid `role` enum %d", r)
    }
    return
    }

    Playground

    关于go - 您应该使用零 “enum”值来表示无效值吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62124488/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com