去JSON命名策略

时间:2016-07-29 05:50:39

标签: json go marshalling unmarshalling

我是Go的新手,我正在探索用于我的一项微服务。我很奇怪Go将对象转换为Json并返回Json。但不幸的是,我发现使用标签名称配置输出字段名称有点困难。

type MyStruct strust{
   MyName string
}

将转换为json

{
    "MyName" : "somestring"
}

但我们正在遵循整个组织的命名策略,以遵循snake_case

{
        "my_name" : "somestring"
}

被认为在我的组织中有效。

我开始在每个字段级别使用json:"my_name,omitempty"等标记。

我想知道有没有办法可以在全局项目级别配置它,所以我不想在每个对象及其字段级别处理它。

1 个答案:

答案 0 :(得分:3)

你可以尝试这样的事情:https://play.golang.org/p/i5X69ywjup

核心功能:

// SnakeCaseEncode snake_case's the given struct's field names.
func SnakeCaseEncode(i interface{}) map[string]interface{} {
    rt, rv := reflect.TypeOf(i), reflect.ValueOf(i)

    if rt.Kind() == reflect.Ptr {
        i := reflect.Indirect(rv).Interface()
        rt, rv = reflect.TypeOf(i), reflect.ValueOf(i)
    }

    out := make(map[string]interface{}, rt.NumField())

    for i := 0; i < rt.NumField(); i++ {
        if strings.Contains(rt.Field(i).Tag.Get("json"), "omitempty") {
            continue
        }

        k := snakeCase(rt.Field(i).Name)

        out[k] = rv.Field(i).Interface()
    }

    return out
}

// snakeCase provides basic ASCII conversion of camelCase field names to snake_case.
func snakeCase(s string) string {
    out := make([]rune, 0, utf8.RuneCountInString(s))

    for i, r := range s {
        if r >= 'A' && r <= 'Z' {
            r += 32

            if i > 0 {
                out = append(out, '_')
            }
        }

        out = append(out, r)
    }

    return string(out)
}

要支持地图,切片等,您必须扩展此简单版本。