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

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


package events


const (

    NEW_USER       = "NEW_USER"

    DIRECT_MESSAGE = "DIRECT_MESSAGE"

    DISCONNECT     = "DISCONNECT"

)

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


type ConnectionPayload struct {

    EventName    string      `json:"eventName"`

    EventPayload interface{} `json:"eventPayload"`

}

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


typescript如果不确定如何在 golang 中执行此操作,这是可能的。


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


红糖糍粑
浏览 125回答 3
3回答

扬帆大鱼

您可以通过生成如下代码来实现。type EventNames stringconst (    NEW_USER       EventNames = "NEW_USER"    DIRECT_MESSAGE EventNames = "DIRECT_MESSAGE"    DISCONNECT     EventNames = "DISCONNECT")然后将您的结构更改为此:type ConnectionPayload struct {    EventName    EventNames  `json:"eventName"`    EventPayload interface{} `json:"eventPayload"`}

智慧大石

目前 go 中没有枚举类型,目前也没有直接的方法来执行与 typescript 相同的规则。go 中的一个常见做法是使用@ttrasn发布的建议:定义自定义类型,并使用您的“枚举”值键入常量:type EventName stringconst (    NEW_USER       EventName = "NEW_USER"    DIRECT_MESSAGE EventName = "DIRECT_MESSAGE"    DISCONNECT     EventName = "DISCONNECT")这允许你在你的 go 代码中标记你期望这样一个值的地方:// example function signature :func OnEvent(e EventName, id int) error { ... }// example struct :type ConnectionPayload struct {    EventName    EventName  `json:"eventName"`    EventPayload interface{} `json:"eventPayload"`}并且它将阻止将平原分配string给EventNamevar str string = "foo"var ev EventNameev = str // won't compileOnEvent(str, 42) // won't compile已知的限制是:在 go 中,总是有一个零值:var ev EventName  // ev is ""字符串文字与类型化变量不同,可以赋值:var ev EventName = "SOMETHING_ELSE"允许铸造:var str string = "foo"var ev EventName = EventName(str)没有检查解组:jsn := []byte(`{"eventName":"SOMETHING_ELSE","eventPayload":"some message"}`)err := json.Unmarshal(jsn, &payload) // no errorhttps://go.dev/play/p/vMUTpvH8DBb如果你想要一些更严格的检查,你将不得不自己编写一个验证器或一个自定义的解组器。

交互式爱情

尝试这个:package mainimport (    "fmt"    "gopkg.in/go-playground/validator.v9")type EventName stringconst (    NEW_USER       EventName = "NEW_USER"    DIRECT_MESSAGE EventName = "DIRECT_MESSAGE"    DISCONNECT     EventName = "DISCONNECT")type ConnectionPayload struct {    EventName    EventName   `json:"eventName" validate:"oneof=NEW_USER DIRECT_MESSAGE DISCONNECT"`    EventPayload interface{} `json:"eventPayload"`}func (s *ConnectionPayload) Validate() error {    validate := validator.New()    return validate.Struct(s)}func main() {    a := ConnectionPayload{        EventName: "NEW_USER",    }    b := ConnectionPayload{        EventName: "NEW_USERR",    }    err := a.Validate()    fmt.Println(a, err)    err = b.Validate()    fmt.Println(b, err)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go