将JSON字符串解组为常量

将JSON字符串解组为常量,json,go,unmarshalling,Json,Go,Unmarshalling,在我的Go代码中,我有以下情况: type Operator int const ( UNKNOWN Operator = iota EQUALS CONTAINS BETWEEN DISTANCE ) type Filter struct { Field string `json:"field"` Operator Operator `json:"operator"` Values []string `json:

在我的Go代码中,我有以下情况:

type Operator int
const (
    UNKNOWN  Operator = iota
    EQUALS
    CONTAINS
    BETWEEN
    DISTANCE
)

type Filter struct {
    Field string      `json:"field"`
    Operator Operator `json:"operator"`
    Values []string   `json:"values"`
}
我期望的JSON如下所示:

{
    "operator": "EQUALS",
    "field": "name",
    "values": [ "John", "Doe" ]
}
我是否可以创建一个映射,以便在筛选器结构中设置正确的运算符常量? 我知道这个接口,但我不认为它真的可以用于常量


我真的很想在我的go代码中保留这些常量,因为当我传递它们时,这很好地加强了类型检查和一致性。

您可以将对象包装在解组器中。 例:

如果不使用包装器,我就不会陷入无限递归

此示例显示了如何解组,但您很可能也希望将其应用于封送,以便使用整型运算符从对象中获得正确的json和运算符字符串


您可能还希望创建一个映射而不是常量。或者两者都可以,创建一个映射并手动使用const和它们的等效字符串填充它。

编码/json解组器接口将使用
操作符
类型,但它必须有一个指针作为其接收器:

func (o *Operator) UnmarshalJSON(b []byte) error {
    str := strings.Trim(string(b), `"`)

    switch {
        case str == "CONTAINS":
            *o = CONTAINS

        default:
            *o = UNKNOWN
            // or return an error...
    }

    return nil
}
JSON解码器将从
过滤器
结构中获取
运算符
字段的地址,并在其上调用
解组JSON
方法

请注意,您可以通过将上面的
UnmarshalJSON
更改为
UnmarshalText
来实现更通用的
encoding/textmarshaler

以下是一个游乐场示例:


可以说,使用字符串基类型来代替运算符可能更简单:

使用运算符指针并在UnmarshalJSON中取消对它的引用正是我今天早上的想法。效果非常好,感谢您提到编码/文本Unmarshaler。Unmarshaler的想法很好,但我想,当过滤器关闭时,我会遇到麻烦封装在另一个应该解析的对象中。谢谢你的回答
func (o *Operator) UnmarshalJSON(b []byte) error {
    str := strings.Trim(string(b), `"`)

    switch {
        case str == "CONTAINS":
            *o = CONTAINS

        default:
            *o = UNKNOWN
            // or return an error...
    }

    return nil
}