为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
红糖糍粑 2022-12-05 16:26:03
我有一个定义特定事件的事件列表(枚举):package eventsconst (    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 来犯错误。
查看完整描述

3 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

您可以通过生成如下代码来实现。



type EventNames string


const (

    NEW_USER       EventNames = "NEW_USER"

    DIRECT_MESSAGE EventNames = "DIRECT_MESSAGE"

    DISCONNECT     EventNames = "DISCONNECT"

)

然后将您的结构更改为此:


type ConnectionPayload struct {

    EventName    EventNames  `json:"eventName"`

    EventPayload interface{} `json:"eventPayload"`

}


查看完整回答
反对 回复 2022-12-05
?
智慧大石

TA贡献1946条经验 获得超3个赞

目前 go 中没有枚举类型,目前也没有直接的方法来执行与 typescript 相同的规则。


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


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


type EventName string


const (

    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给EventName


var str string = "foo"

var ev EventName


ev = str // won't compile

OnEvent(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 error

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


如果你想要一些更严格的检查,你将不得不自己编写一个验证器或一个自定义的解组器。


查看完整回答
反对 回复 2022-12-05
?
交互式爱情

TA贡献1712条经验 获得超3个赞

尝试这个:


package main


import (

    "fmt"


    "gopkg.in/go-playground/validator.v9"

)


type EventName string


const (

    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)

}


查看完整回答
反对 回复 2022-12-05
  • 3 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信