在 Golang 中将 JSON 中的字符串解析为枚举

swd*_*don 5 enums json go unmarshalling

我有一个枚举定义为

type MyEnum int

const(
   FirstEnum MyEnum = iota
)
Run Code Online (Sandbox Code Playgroud)

然后,我有一个包含键值对的 json "Key": "FirstEnum"。我就是这样解组的。

var data map[string]interface{}
err := json.Unmarshal([]byte(json), &data)
x := data["key"].(MyEnum)
Run Code Online (Sandbox Code Playgroud)

但是,当我运行此命令时,我收到错误:

panic: interface conversion: interface {} is string, not ps.Protocol [recovered]
        panic: interface conversion: interface {} is string, not ps.Protocol
Run Code Online (Sandbox Code Playgroud)

有没有办法让它像 Go 中枚举的字符串表示形式到枚举类型的正常转换一样工作?

swd*_*don 4

我想出了一些类似的方法(至少适用于我目前的情况):

用于string类似enum常量:

type MyEnum string

const(
   FirstEnum MyEnum = "FirstEnum"
)
Run Code Online (Sandbox Code Playgroud)

现在,使用解码 json 来自定义类型,如此处所述

data := MyJsonStruct{}
err := json.Unmarshal([]byte(json), &data)
Run Code Online (Sandbox Code Playgroud)

MyJsonStruct看起来像:

type MyJsonStruct struct {
    Key MyEnum
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使 MyJsonStruct 实现该Unmarshaler接口,以便您可以验证给定的值。

func (s *MyJsonStruct) UnmarshalJSON(data []byte) error {
    // Define a secondary type so that we don't end up with a recursive call to json.Unmarshal
    type Aux MyJsonStruct;
    var a *Aux = (*Aux)(s);
    err := json.Unmarshal(data, &a)
    if err != nil {
        return err
    }

    // Validate the valid enum values
    switch s.Key {
    case FirstEnum, SecondEnum:
        return nil
    default:
        s.Key = ""
        return errors.New("invalid value for Key")
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

  • 如果字符串与枚举值之一不匹配,这种方法似乎不会引发任何错误。 (4认同)