Go:如何使用枚举作为类型?

Kar*_*mar 14 enums go

我有一个定义特定事件的事件列表(枚举):

package events

const (
    NEW_USER       = "NEW_USER"
    DIRECT_MESSAGE = "DIRECT_MESSAGE"
    DISCONNECT     = "DISCONNECT"
)
Run Code Online (Sandbox Code Playgroud)

并且有一个结构体将使用此枚举作为其属性之一

type ConnectionPayload struct {
    EventName    string      `json:"eventName"`
    EventPayload interface{} `json:"eventPayload"`
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以用作EventName而不是字符串的enum类型?

这是可能的,typescript不确定如何在 golang 中做到这一点。

我希望开发人员通过枚举强制使用正确的事件名称,而不是通过使用任何随机字符串作为 eventname 来犯错误

LeG*_*GEC 19

目前 Go 中没有枚举类型,并且目前没有直接的方法来强制执行与 TypeScript 相同的规则。


go 中的常见做法是使用@ttrasn发布的建议:

定义自定义类型,并使用“枚举”值定义类型常量:

type EventName string

const (
    NEW_USER       EventName = "NEW_USER"
    DIRECT_MESSAGE EventName = "DIRECT_MESSAGE"
    DISCONNECT     EventName = "DISCONNECT"
)
Run Code Online (Sandbox Code Playgroud)

这允许您在 go 代码中标记您期望这样的值的位置:

// example function signature :
func OnEvent(e EventName, id int) error { ... }

// example struct :
type ConnectionPayload struct {
    EventName    EventName  `json:"eventName"`
    EventPayload interface{} `json:"eventPayload"`
}
Run Code Online (Sandbox Code Playgroud)

它会阻止将普通分配stringEventName

var str string = "foo"
var ev EventName

ev = str // won't compile
OnEvent(str, 42) // won't compile
Run Code Online (Sandbox Code Playgroud)

已知的限制是:

https://go.dev/play/p/vMUTpvH8DBb

如果您想要进行更严格的检查,则必须自己编写验证器或自定义解组器。


ttr*_*asn 9

您可以通过生成如下代码来完成此操作。


type EventNames string

const (
    NEW_USER       EventNames = "NEW_USER"
    DIRECT_MESSAGE EventNames = "DIRECT_MESSAGE"
    DISCONNECT     EventNames = "DISCONNECT"
)
Run Code Online (Sandbox Code Playgroud)

然后将您的结构更改为:

type ConnectionPayload struct {
    EventName    EventNames  `json:"eventName"`
    EventPayload interface{} `json:"eventPayload"`
}
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚尝试过这个,这给出了有效值的智能感知,但如果我将随机字符串分配给“EventName”,它不会抛出任何错误 (4认同)